线性表(List):零个或者多个数据元素的有限序列。
线性表的存储结构大约分为三种:1,顺序存储结构 2,链式存储结构 3,静态链表。
顺序存储结构的线性表是由数组实现的,由于C++不支持变长数组,所以顺序存储结构的线性表在定义时就指定了长度,这是一个很大的问题。譬如说,一个顺序存储结构的线性表的长度为10000,我们写程序用到了这个线性表,但是只往表里添加了十几个数据,这显然对空间造成了极大的浪费。所以说,这种结构的线性表并适用于实际的应用。
链式存储结构的线性表实现了空间的动态分配,这一概念解决了顺序存储结构的问题,在大部分数据结构的书的讲解中,链式线性表都作为重点来讲解。然而,几乎所有的数据结构书都是在讲链式线性表这种结构概念,书中的代码几乎清一色的伪代码,使用抽象数据类型,这种写法不能够在计算机中直接运行,既然数据类型都抽象了,何不用模板类来实现一个线性表。
线性表是一种最基础的数据结构,所以应用也广泛,在编写线性表时,应该尽量考虑它的灵活性,本文采用了双向链表结构来构成线性表,也就是说,线性表的一个结点有三项:数据性,next指针,pervious指针。构造这样的结点,线性表可以灵活的从头和尾部插入结点。
结点:
双向链式线性表(本文定义的线性表,头结点和尾结点不存放数据):
空的线性表:
push data to list:
pop data from list:
code:
#ifndef BASEDEF_H__ #define BASEDEF_H__ template<class ADT> struct Node { Node(ADT data) { this->data = data; previous = nullptr; next = nullptr; } Node()//用于建立无值得头结点 { previous = nullptr; next = nullptr; } ADT data; Node<ADT> *previous; Node<ADT> *next; }; //双向链式线性表 template<class ADT> class zlLinkList { public: zlLinkList(); ~zlLinkList(); bool clear(); public: bool PushHead(ADT data); bool PopHead(ADT &data); bool PushBack(ADT data); bool PopBack(ADT &data); ADT at(int index); int size(); private: Node<ADT> *head;//逻辑头 Node<ADT> *tail;//逻辑尾 int listSize; }; //模板实现 template<class ADT> zlLinkList<ADT>::zlLinkList() { head = new Node<ADT>;//不存值 tail = new Node<ADT>;//不存值 head->next = tail; tail->previous = head; listSize = 0; } template<class ADT> zlLinkList<ADT>::~zlLinkList() { this->clear(); delete head; delete tail; } template<class ADT> bool zlLinkList<ADT>::clear() { if (head->next == tail) { return false; } Node<ADT> *p = nullptr; while (head->next != tail) { p = head->next; head->next = p->next; (p->next)->previous = head; delete p; } return true; } template<class ADT> int zlLinkList<ADT>::size() { return listSize; } template<class ADT> bool zlLinkList<ADT>::PushHead(ADT data) { Node<ADT> *N = new Node<ADT>(data); Node<ADT> *p;//辅助指针 p = head->next; head->next = N; N->next = p; p->previous = N; N->previous = head; listSize++; return true; } template<class ADT> bool zlLinkList<ADT>::PushBack(ADT data) { Node<ADT> *N = new Node<ADT>(data); Node<ADT> *p;//辅助指针 p = tail->previous; p->next = N; N->next = tail; tail->previous = N; N->previous = p; listSize++; return true; } template<class ADT> bool zlLinkList<ADT>::PopHead(ADT &data) { if (head->next == tail) { return false; } Node<ADT> *p = nullptr; p = head->next; head->next = p->next; (p->next)->previous = head; data = p->data; delete p; listSize--; return true; } template<class ADT> bool zlLinkList<ADT>::PopBack(ADT &data) { if (tail->previous == head) { return false; } Node<ADT> *p = nullptr; p = tail->previous; tail->previous = p->previous; (p->previous)->next = tail; data = p->data; delete p; listSize--; return true; } template<class ADT> ADT zlLinkList<ADT>::at(int index) { Node<ADT> *p = head->next;//辅助指针 for (int i = 0; i < index; i++) { p = p->next; } return p->data; } #endif
demo:
#include"iostream" #include"BaseStruct.h" using namespace std; int main(int argv, char *argc[]) { zlLinkList<char> m; m.PushHead(‘a‘); m.PushHead(‘b‘); m.PushHead(‘c‘); m.PushHead(‘d‘); char data; m.PopBack(data); std::cout << data <<m.size()<< endl; m.PopBack(data); std::cout << data << m.size() << endl; m.PopBack(data); std::cout << data << m.size() << endl; m.PopBack(data); std::cout << data << m.size() << endl; return 0; }
输出:
时间: 2024-12-29 01:48:30