线性表的两种实现 -- 顺序表和链表(C++)
来源:互联网 发布:java中如何使用debug 编辑:程序博客网 时间:2024/06/05 02:03
线性表抽象类声明
#ifndef ADT_H#define ADT_H//线性表ADTtemplate <typename E>class List{private: void operator =(const List){} //赋值运算符 List(const List&){} //复制构造函数public: List(){} //默认构造函数 virtual ~List(){} //析构函数 //清空所有元素 virtual void clear() = 0; //在当前位置插入元素item virtual void insert(const E& item) = 0; //list尾部添加一个元素 virtual void append(const E& item) = 0; //删除并返回当前位置的元素 virtual E remove() = 0; //设置当前位置为list的开始位置 virtual void moveToStart() = 0; //设置当前位置为list的末尾位置 virtual void moveToEnd() = 0; //当前位置左移一个位置,不改变元素 virtual void prev() = 0; //当前位置右移一个位置,不改变元素 virtual void next() = 0; //返回元素数量--即获取长度 virtual int length() const = 0; //返回当前元素位置 virtual int currPos() const = 0; //设置当前位置 virtual void moveToPos(int pos) = 0; //获取当前元素 virtual const E& getValue() const = 0;};#endif
顺序表的实现
#include "ADT.h"template <typename E>class AList : public List<E>{private: int maxSize; //list 最大容量 int listSize; //list 当前元素个数 int curr; //当前元素位置 E* listArray; //list指针public: AList(int size = defaultSize){ //构造函数 maxSize = size; listSize = curr = 0; listArray = new E[maxSize]; } ~AList(){ delete[] listArray; } //析构函数 void clear(){ //重新初始化list delete [] AList; listSize = 0; listArray = new E[maxSize]; } //在当前位置插入 it 元素 void insert(const E& it){ Assert(listSize < maxSize, "List capacity exceeded"); for (int i = listSize; i > curr; i--) listArray[i] = listArray[i - 1]; listArray[curr] = it; listSize++; } //末尾添加元素 void append(const E& it){ Assert(listSize < maxSize, "List capacity exceeded"); listArray[listSize++] = it; } //删除并返回当前位置的元素 E remove(){ Assert(listSize < maxSize, "List capacity exceeded"); E it = listArray[curr]; for (int i = curr; i < listSize - 1; i++) listArray[i] = listArray[i + 1]; listSize--; return it; } void moveToStart(){ curr = 0; } //位置重置为start位置 void moveToEnd(){ curr = listSize; } //位置重置为end位置 void prev(){ if (curr != 0) curr--; }; //上一个元素位置 void next(){ if (curr < listSize) curr++ }; //下一个元素位置 //返回list元素个数 int length() const { return listSize }; //返回当前元素位置 int currPos() const { return curr }; //设置当前list位置为 pos void moveToPos(int pos){ Assert((pos >= 0) && (pos <= listSize), "pos out of range"); curr = pos; } //获取当前位置元素 const E& getValue() const { Assert((curr >= 0) && (curr <= listSize), "No current element"); return listArray[curr]; }};
单链表的实现
#include "ADT.h"//单链表结点定义template <typename E>class Link{public: E element; //节点的值 Link* next; //next Link(const E& elemval, Link* nextval = NULL){ element = elemval; next = nextval; } Link(Link* nextval = NULL){ next = nextval; }};template <typename E>class LList: public List<E>{private: Link<E>* head; Link<E>* tail; Link<E>* curr; int cnt; //初始化 void init(){ curr = tail = head = new Link<E>; cnt = 0; } //清空所有元素 void removeall(){ while (head != NULL){ curr = head; head = head->next; delete curr; } }public: LList(int size = defalueSize){ init(); } //构造函数 ~LList(){ removeall(); } //析构函数 void print() const; //print List void clear(){ removeall(); init(); } //clear List void insert(const E& it){ curr->next = new Link<E>(it, curr->next); if (tail == currr) tail = curr->next; cnt++; } void append(const E& it){ tail = tail->next = new Link<E>(it, NULL); cnt++; } E remove(){ Assert(curr->next != NULL, "No element"); E it = curr->next->element; //保存数据 Link<E>* ltemp = curr->next; //保存链表节点 if (tail == curr->next) tail = curr; //重置尾节点 curr->next = curr->next->next; //删除节点 delete ltemp; //释放空间 cnt--; //cnt - 1 return it; } //移动至链表开始位置 void moveToStart(){ curr = head; } //移动至链表尾端 void moveToEnd(){ curr = tail; } //上一个节点 void prev(){ if (curr == head) return; Link<E>* temp = head; while (temp->next != curr){ temp = temp->next; } curr = temp; } //下一个节点 void next(){ if (curr != tail) curr = curr->next; } //返回长度 int length() const { return cnt; } //链表当前位置 int currPos() const{ Link<E>* temp = head; int i; for (i = 0; curr != temp; i++){ temp = temp->next; } return i; } //移动至链表的pos位置 void moveToPos(int pos){ Assert((pos >= 0) && (pos <= cnt), "Pos out of range"); curr = head; for (int i = 0; i < pos; i++) curr = curr->next; } //获取当前元素 const E& getValue() const { Assert(curr->next != NULL, "No Value"); return curr->next->element; }};
线性表两种实现方法的比较
空间方面:
顺序表的缺点:大小事先固定。虽然便于分配空间,但是元素只有少数的几个时造成空间的浪费。
链表的优点:只有实际在链表中的对象需要空间,只要存在可用的内存空间分配,链表中元素的个数没有限制。
顺序表的优点是对于表中的每一个元素没有浪费空间,而链表需要在每个节点附加上一个指针。在可以大概估计出线性表长度的情况下,顺序表比链表有更高的空间效率。
随机访问元素:
取出线性表中第i个元素这样的按位置随机访问,使用顺序表更快些;通过next和prev可以很容易调整当前位置向前或向后,这两种操作需要的时间为O(1)。
相比之下,单链表不能直接访问前面的元素,按位置只能从表头(或者当前位置)开始,直到找到那个特定的位置。假定表中每个位置是由prev和moveToPos平均访问到的,那么访问线性表第i个元素的操作所需的平均情况下时间和最差情况下时间都是O(n)。
插入和删除元素:
给出指向链表中合适位置的指针后,insert和remove函数所需要的时间仅为O(1)。
而顺序表必须在数组内将其余元素向前或向后移动。这种方法所需的平均情况下时间和最差时间均为O(n)。
对于许多应用,插入和删除是最主要的操作,因此他们的时间效率是举足轻重的。仅就这个原因而言,链表往往比顺序表更好。
0 0
- 线性表的两种实现 -- 顺序表和链表(C++)
- 基于C语言的线性表操作,包含单链表和顺序线性表两种类型
- 【线性表一:】两种存储结构的代码实现:顺序存储和链式存储
- 线性表的顺序表示和实现(C语言描述)
- 线性表的顺序实现(C语言)
- 线性表的顺序实现(C++)
- 线性表的顺序实现(c语言)
- C语言实现线性顺序链表
- 线性表的顺序表示和实现
- 线性表的顺序表示和实现
- 线性表的顺序表示和实现
- 线性表的顺序表示和实现
- 线性表的顺序表示和实现
- 线性表的顺序表示和实现
- 线性表的顺序表示和实现
- 线性表的顺序表示和实现
- 线性表的顺序表示和实现
- 线性表的顺序表示和实现
- 奇偶行并排显示
- java synchronized详解
- php中使用redis
- Flume核心概念
- Android音频通讯
- 线性表的两种实现 -- 顺序表和链表(C++)
- Java语言实现二叉树
- java Object转Map 小工具
- TCP的状态(SYN,FIN,ACK,PSH,RST,URG)
- 文件重命名批量处理(Matlab)
- PDF文件如何转换成Excel
- (第18讲)java数据结构的堆栈与内存区的堆栈(总结各大神的见解)
- Retrofit 入门和提高
- Sublime Text 使用介绍、全套快捷键及插件推荐