抽象数据类型ADT中的表可以用简单的数组实现。但是用数组实现有两个弊端:
1)首先要对表的大小的最大值进行估计,以便于创建相应长度的数组,如果过大,会浪费很多空间。
2)插入和删除操作在数组中的代价是昂贵的。因为插入一个元素或者删除一个元素会使得其他元素的位置需要相应的变化。
为了克服上面的困难,我们需要使得表的存储不连续,避免整体或者大规模的数据移动。链表的思想由此而生:
链表是由一系列不必在内存中相连的结构组成。每个结构包含一个表元素和一个指向后继结构的指针。
下面是个人学习链表是练习用C++写的实现代码。实现了链表的一些节本功能,如创建链表,插入操作,删除操作,查找,打印等功能。
#include <iostream>using namespace std;class Listitem {public: Listitem():elem(0),next(NULL) {} //定义链表中每个节点的结构 int elem; Listitem* next;};class List {public: List():head(NULL){} //构造函数 void Init(); //初始化一个空表 void Create(); //创建一个链表 void Isempty(); //判断链表是否为空 void Insert(); //插入元素 void Delete(); //删除元素 void Find(); //查找某个元素 void Reverse(); //逆置一个链表 void Print(); //打印链表元素 ~List(); //析构函数private: Listitem *head; //头指针};void List::Init(){ head = new Listitem; //创建一个带有头结点的空表 head->elem = 0; head->next = NULL; cout<<"empty List creation has been conpleted!"<<endl;}void List::Create() { cout<<"please dinfine how many elements in the List"<<endl; int num,N; //输入你想创建的链表包含的元素个数 cin>>N; cout<<"please input "<<N<<" elements in the List"<<endl; Listitem *tmp = head; for(int i=0; i!=N; i++) { Listitem *p = new Listitem; cin>>num; p->elem = num; p->next = NULL; tmp->next = p; tmp=p; } cout<<N<<"-element List creation has been conpleted!"<<endl;}
void List::Isempty() { bool a= ((this->head->next)==NULL); if (a==1) cout<<"The List is empty!"<<endl; //判断为空 else cout<<"The List is non-empty"<<endl;//判断为非空}void List::Insert() { cout<<"please input the position you want to intert this elements"<<endl; int pos,ele; cin>>pos; Listitem *tmp1; Listitem *tmp = head; for( int i=1; i!=pos; i++) tmp=tmp->next; //找到要插入的位置的前一位置 tmp1 = new Listitem; cout<<"please input the value for the element"<<endl; cin>>ele; tmp1->elem=ele; tmp1->next=tmp->next; tmp->next = tmp1; cout<<"Insert has been finished"<<endl;}void List::Delete() { int ele; cout<<"please input the value for the element you want to delete"<<endl; cin>>ele; Listitem *tmp = head; while(tmp->next!=NULL && tmp->next->elem != ele){ tmp=tmp->next; } if(tmp->next == NULL) cout<<"the delete element has not been found in the list"<<endl; else { Listitem *tmp1 =tmp->next; tmp->next=tmp1->next; delete tmp1; cout<<"Delete has been finished"<<endl; }}void List::Find() { int ele,ii=1; cout<<"please input the value for the element you want to find"<<endl; cin>>ele; Listitem *tmp = head->next; while(tmp!=NULL && tmp->elem != ele){ ii++; tmp=tmp->next; } if(tmp == NULL) cout<<"the element has not been found in the list"<<endl; if(tmp != NULL) cout<<"the element has been found in the list and it is the " << ii<<"th element in this List"<<endl;}void List::Reverse() { Listitem *p, *q; p=head->next; head->next=NULL; while(p!=NULL) { q=p->next; p->next=head->next; head->next=p; p=q; }}
void List::Print() { cout<<"<"; for(Listitem *iter = head->next; iter!=NULL; iter=iter->next) cout<<iter->elem<<" "; cout<<">"<<endl;}List::~List() {
//这个析构函数是要得的,因为使用new动态创建的Listitem结构在程序运行玩不会自动运行析构函数的,
//必须在删除动态创建对象的指针后,才能运行析构函数,这样可以避免内存泄露。 Listitem *p = head->next; while(p!=NULL) { head->next=p->next; delete p; p=head->next; } delete head; cout<<"the whole list has been deleted"<<endl;}int main(){ cout<<"This is a practice of List ! Please select the NUM for corresponding function:"<<endl; cout<<"(1):Initiate a empty List (2)Isempty (3) Create (4)Insert (5)Delete (6)Find (7) Reverse (8)Print"<<endl; List LL; int n; while(cin>>n){ cout<<"(1):Initiate a empty List (2)Isempty (3) Create (4)Insert (5)Delete (6)Find (7) Reverse (8)Print"<<endl; switch(n){ case 1: LL.Init(); break; case 2: LL.Isempty(); break; case 3: LL.Create(); break; case 4: LL.Insert(); break; case 5: LL.Delete(); break; case 6: LL.Find(); break; case 7: LL.Reverse(); break; case 8: LL.Print(); } } }上述程序个人已经DEBUG过了,应该能够基本实现功能。