顺序表的优缺点.ppt

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

void FreeNode(Node<T>* ptr)
{
if (!ptr) {
cerr << "FreeNode:invalid node pointer!"<< ndl;return;
} delete ptr; }
Node ptr
data next
4.2.3 链表类
//算法4.8: 构造函数(建立一个空链表)
front = rear = newNode;
position = 0;
}
newNode
front rear
else if (!prevPtr) { // 在表头节点处插入
4.2.3 链表类
//算法4.16: 在当前结点处插入新结点的成员函数
template <class T>
void LinkedList <T>::InsertAt(const T& item)
{
Node<T>* newNode;
if (!size) {
// 在空表中插入
newNode = GetNode(item, front);
结点 node 由一个数据域(data),一个或几个指针域 (next,或称链域)组成。
4.2 单链表
例4-1:给定线性表 A={31,27,59,40,58},采用 链表存储,则对应的链表如图4.1所示:
head
31
27
59
40
58 ^
| 表头
| 表尾
用指针将互不相连的内存结点串成的线性表称为链表,链 表为线性表的链式存储结构。
q = new int(100);
p = new T[MaxSize]; q = new int[100];
delete p;
delete q;
delete[] p;
delete[] q;
4.2 单链表
单链表是最简单的链式结构,也是最基本的链式结构。 4.2.1 基本概念
在链表中,基本的元素称为结点,一个链表由若干个 结点链接而成。
data next ptr
4.2.3 链表类
#include “node.h”
template <class T>
class LinkedList
{
private:
Node<T>* front;
// 指向表头结点的指针
Node<T>* rear;
// 指向表尾结点的指针
Node<T>* prevPtr; // 指向前一结点的指针
int NextNode(void);
int SetPosition(int pos);
int GetPosition(void) const;
void InsertAt(const T& item);
void InsertAfter(const T& item);
void DeleteAt(void);
Node<T>* NextNode(void) const;
void InsertAfter(Node<T>* p);
Node<T>* DeleteAfter(void);
};
4.2.2 结点类
//算法 4.1: 结点类的构造函数 template <class T> Node<T>::Node(const T& item, Node<T>* ptr) :
data(item), next(ptr) {}
4.2.2 结点类
//算法 4.2: 结点类的析构函数 template <class T> Node<T>::~Node(void) {}
4.2.2 结点类
//算法 4.3: 结点类中返回私有成员 next 值(获 取下一结点指针)的函数
Node<T>* currPtr;
// 指向当前结点的指针
int size;
// 链表结点个数
int position;
// 当前位置索引
Node<T>* GetNode(const T& item, Node<T>* ptr = NULL);
void FreeNode(Node<T>* p);
if (!newNode)
{
cerr<<"GetNode:Memory allocation failed!"<<endl;
return NULL;
}
return newNode;
Node
}
newNode
data next
4.2.3 链表类
//算法4.7: 释放结点空间的成员函数
template <class T>
template <class T> LinkedList<T>::LinkList(void): front(NULL),
rear(NULL), prevPtr(NULL), currPtr(NULL), size(0), position(-1) {}
4.2.3 链表类
//算法4.9: 析构函数 template <class T> LinkedList<T>::~LinkList(void) { Clear(); // 清除链表所有结点 }
}
front
else {
position = size;
}
return position;
prevPtr currPtr position=2, size=5
}
4.2.3 链表类
//算法4.14: 重置当前结点位置的成员函数
template <class T>
int LinkedList<T>::SetPosition(int pos)
移动结点,效率低。
链表:用一组地址任意的存储单元存储线性表中的各 个数据元素,为了保证其逻辑结构,每个结点中包含 一个指向其后继的指针。
链表适合于需要频繁地插入和删除结点,以及事先无 法确定表的大小的情形。
head
31
27
59
40
58 ^
4.1 动态数据结构
动态数据结构:指在运行时才能确定所需内存 大小的数据结构。
{
if (!size) return -1;
// 若链表为空则返回
pos = min(size, max(0, pos)); // 0≤pos≤size
prevPtr = NULL;
currPtr = front;
position = 0;
front
for (int k = 0; k < pos; k++) { // 寻找对应节点
如果线性链表中的每个结点只有一个指针域,则称此
线性链表为单链表。
4.2 单链表
在上图中,head 称为头指针。不含结点的链表称为空链表,此 时,head 为空(NULL)。
为了操作方便起见,实际应用中,可采用附加头结点的方式来组 织链表,此时,头指针所指向的结点不是表头,而是一个特殊的 结点,这个结点不用来存储任何数据。附加头结点的指针所指向 的结点才是表头结点。
void DeleteAfter(void);
T GetData(void) const;
void SetData(const T& item);
void Clear(void);
};
4.2.3 链表类
例4-3:对于例4-1中给出的一组数据,采用链 表类进行存储时,对应的链表对象结构如图 4.5所示:
front
31
27
59
40
58 ^
rear
prevPtr
currPtr
Size=5
Position=2
4.2.3 链表类
//算法4.6: 申请结点空间的成员函数
template <class T>
Node<T>* GetNode(const T& item, Node<T>* ptr)
{
Node<T>* newNode = new Node<T>(item, ptr);
4.2.3 链表类
//算法4.10: 重载赋值运算符成员函数
template <class T>
LinkedList<T>& LinkedList<T>::operator=
(const LinkedList<T>* orgList)
{
Node<T>* p = orgList.front;

return *this;
}
4.2.3 链表类
//算法4.11: 取表大小的成员函数 template <class T> int LinkedList<T>::Size(void) const { return size; }
4.2.3 链表类
//算法4.12: 判断表是否为空的成员函数 template <class T> boolean LinkedList<T>::IsEmpty(void) const { return size ? FALSE : TRUE; }
Clear();
// 清空本链表
while (p) // 将orgList中的元素复制到本表
{
InsertAfter(p->data);
p = p->NextNode();
orgList
}
p

SetPosition(orgList.position); data next
// 设置当前节点
front
例4-2:对于例4-1中给出的一组数据,采用 附加头结点的链表进 行存储时,对应的链表如图4.4所示:
head
31
27
59
40
58 ^
|
|
|
附加头结点 front
rear
线性链表的存储结构示例:
存储地址 数据域 指针域
5 → 8 →1 9 → 2 → 3 ^
头指针h
7
13
31
43
2 43
8 13
public:
LinkedList(void);
~LinkedList(void);
LinkedList<T>& operator=
(const LinkedList<T> *orgList);
int Size(void) const;
bool IsEmpty(void) const;
动态数据结构所使用的内存称为动态内存。动 态申请的内存在不需要时必须及时释放。
C++为处理动态内存提供了一对操作符new和 delete。它们和指针变量结合起来,用来申请 和释放动态内存。
动态内存的申请和释放
T* p;
int* q;
p = new T;
q = new int;
p = new T(value);
4.2.3 链表类
//算法4.13: 将后继结点设置为当前结点的成员函数
template <class T>
int LinkedList<T>::NextNode(void) {
if (position<size) {
position++;
prevPtr = currPtr;
currPtr = currPtr->NextNode();
由一个数据域data一个或几个指针域例41给定线性表a3127594058采用链表存储则对应的链表如图41所示head表头用指针将互不相连的内存结点串成的线性表称为链表链表为线性表的链式存储结构
第四章 链 表
顺序表的优缺点:
优点:存储密度高、可以随机存取结点。 缺点:①长度为定值,中途无法扩充。②插入删除需要
template <class T> Node<T>* Node<T>::NextNode(void) const { return next; }
4.2.2 结点类
//算法 4.4 结点类中在当前结点后插入一个结 点的函数
template <class T>
void Node<T>::InsertAfter(Node<T>* p)
31
91
57
3^
4.2.2 结点类
template <class T> class Node
Node
{
private:
Node<T>* next;
data next
public:
T data;
Node(const T& item, Node<T>* ptr=NULL);
~Node(void);
{
p->next = next;
next = p;
p
}
data next
4.2.2 结点类
//算法 4.5 结点类中删除当前结点后继的函数 template <class T> Node<T>* Node<T>::DeleteAfter(void) { Node<T>* ptr = next; if (ptr == NULL) return NULL; next = ptr->next; return ptr; }
position++; prevPtr currPtr
prevPtr = currPtr;
currPtr = currPtr->NextNode();
}
return position;
// 返回当前节点位置
}
4.2.3 链表类
//算法4.15: 取当前结点位置的成员函数 template <class T> int LinkedList <T>::GetPosition(void) const { return position; }
相关文档
最新文档