链表即采用链式存储方式的线性表。为了表示每个数据元素 及其后继元素 间的逻辑关系,我们在存储数据元素 的同时,必须存储一个指示其后继 的存储位置的信息 。我们称这样的二元组 为一个结点 ( Node ) 。不多说,直接贴代码吧。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
struct Node
{
int data;
Node *next;
};
class List
{
public:
Node *head;
List()//构造函数初始化一个空链表
{
head=NULL;
}
void Create()//创建一个链表
{
Node *p=new Node;
p->data = 0;
p->next = NULL;
head=p;
int n;
Start:
cout<<"请输入链表的长度: "<<endl;
cin>>n;
if(n<0)
{
cout<<"您的输入有误,请从新输入!"<<endl;
goto Start;
}
else
{
cout<<"请依次输入 "<<n<<" 个值:"<<endl;
}
cout<<"请输入第 1 个值:"<<endl;//这里以链表第一个值作为头结点
cin>>p->data;
for(int i = 1; i < n; i++)
{
Node *q=new Node;
q->next = NULL;
cout<<"请输入第 "<<i+1<<" 个值:"<<endl;
cin>>q->data;
//q->next=p->next;
p->next=q;
p=q;
}
}
~List()//析构函数释放内存
{
Node *p;
cout<<"链表已销毁"<<endl;
while(head)
{
p=head->next;
delete [] head;
head=p;
}
}
void Destroy()//销毁链表
{
Node *p;
cout<<"链表已销毁"<<endl;
while(head)
{
p=head->next;
delete [] head;
head=p;
}
}
void Clear()//清空链表,保留第一个结点head,并设其数据域为0,如有需要可以继续添加新结点
{
Node *p,*q;
if(head == NULL)
{
cout<<"这已经是一个空链表"<<endl;
}
p=head->next;
while(p!=NULL)
{
q=p->next;
delete [] p;
p=q;
}
head->next=NULL;
head->data=0;
}
List *TailInsert(int m)//在表的尾端添加数值m
{
Node *p=head;
while(p->next != NULL)
{
p=p->next;
}
Node *q=new Node;
q->data=m;
q->next=NULL;
p->next=q;
List *A=new List;
A->head=this->head;
return A;
}
void TailInsertMore(int a[],int m)//在尾段依次添加m个元素的数组,也可以看做一种建表的方法
{
for(int j=0;j<m;j++)
{
this->head=(this->TailInsert(a[j]))->head;
}
}
void Insert(int i,int m)//在表的第i个位置插入一个数m
{
Node *p=head;
int j=1;
while(p && j<i-1)
{
p=p->next;
j++;
}
if(!p || j>i-1)
{
cout<<"插入位置有误"<<endl;
}
else
{
Node *q;
q=new Node;
q->data=m;
q->next=p->next;
p->next=q;
}
}
void Delete(int i)//删除表的第i个元素,返回其值m
{
int m;
Node *p=head;
int j=1;
while(p->next && j<i-1)
{
p=p->next;
j++;
}
if(!(p->next)||j>i-1)
cout<<"删除位置错误"<<endl;
else
{
Node *q=new Node;
q=p->next;
p->next=q->next;
m=q->data;
delete q;
}
cout<<"被删除的 "<<i<<" 位置处的值为"<<m<<endl;
}
void Output()//输出链表的数据域和指针域
{
if(head==NULL)
{
cout<<"该表为空表"<<endl;
}
Node *current=head;
while(current!=NULL)
{
cout<<"在内存地址 "<<current<<" 上存储的数据是 "<<current->data<<", 存储的指针是 "<<current->next<<"."<<endl;
current=current->next;
}
}
int Length()//链表长度
{
Node *p=head;
int j=0;
while(p!=NULL)
{
p=p->next;
j++;
}
cout<<"链表长度为 "<<j<<endl;
return j;
}
void Reverse()//倒序排列
{
if(head==NULL)
{
return; //链表为空链表
}
Node *current = head -> next,*node; //从头结点开始遍历
head -> next = NULL;
while(current != NULL)
{
node = current -> next; //记住当前操作节点的后面节点的地址
current -> next = head;
head = current;
current = node;
}
}
void Sort()//利用冒泡排序从大到小排列
{
Node *s=head;
while(s->next!=NULL)
{
Node *p=s;
Node *q=p->next;
while(q!=NULL)
{
if(p->data<=q->data)
{
p=q;
q=q->next;
}
else
{
Node *r=new Node;
int m=p->data;
r=p;
r->data=q->data;
p=q;
p->data=m;
q=p->next;
}
}
int l=s->data;
s->data=p->data;
p->data=l;
s=s->next;
}
}
void Delete_Repeat()//删除链表中重复出现的元素,只保留第一个出现的元素,并输出各出现几次
{
Node *p = head;
if(p == NULL)
cout<<"链表为空.";
if(p->next == NULL)
cout<<"链表只有一个元素.";
while(p->next != NULL)
{
Node *q=p;
while(q->next!=NULL)
{
if(p->data == q->next->data)
{
while(p->data == q->next->data && q->next->next != NULL)
{
q->next=q->next->next;
}
q=q->next;
}
else
{
q = q->next;
}
}
p=p->next;
}
Node *r=head,*s=head;
while(r->next != NULL)
{
r=r->next;
}
int i=0;
while(s->next->next != NULL)
{
if(s->data == r->data)
{
i++;
}
s=s->next;
}
if(i>0)
{
s->next = NULL;
}
}
void Get()//获取链表指定位置的元素值
{
cout<<"请输入需要查找的位置:"<<endl;
int k;
cin>>k;
Node *p=head;
int l=1;
while(p!=NULL && l<k)
{
p=p->next;
l++;
}
if(p==NULL || l<k)
{
cout<<"所查找位置不存在"<<endl;
}
else
{
int e=p->data;
cout<<"第 "<<k<<" 个位置处的值为"<<e<<endl;
}
}
int Search()//在链表中查找某个数是否出现,并打印出现的位置和总次数
{
int k;
cout<<"请输入要查找的值:"<<endl;
cin>>k;
Node *p=head;
int j=0,i=0;
while(p!=NULL)
{
i++;
if(p->data==k)
{
j++;
p=p->next;
cout<<"值 "<<k<<" 出现在链表的第 "<<i<<" 个位置"<<endl;
}
else
{
p=p->next;
}
}
cout<<"值 "<<k<<" 在链表中出现的总次数为 "<<j<<endl;
return j;
}
};
List Merge(List A,List B)//合并两个链表为第三个链表并返回
{
List C;
Node *a=A.head;
Node *c=C.head=A.head;
Node *b=B.head;
while(c->next!=NULL)
{
c=c->next;
}
c->next=b;
return C;
}
int main()
{
cout<<"*****链表初始化*****"<<endl;
List A,B,C;
A.Length();
A.Output();
cout<<endl;
cout<<"*****创建新表并求表长*****"<<endl;
A.Create();
A.Length();
A.Output();
cout<<endl;
cout<<"*****清空数据并重新插入*****"<<endl;
A.Clear();
int a=7; int c=5; //可以设置代码由用户输入
int b[]={3,0,9,4,7,3,2,4}; //同上
A.TailInsert(a)->Output(); //插入一个数
cout<<endl;
A.Output();
cout<<endl;
A.TailInsertMore(b,c); //插入一个数组
A.Output();
cout<<"*****链表查找操作*****"<<endl;
A.Get();
A.Search();
cout<<"*****从大到小排列*****"<<endl;
A.Sort();
A.Output();
cout<<"*****从小到大排列*****"<<endl;
A.Reverse();
A.Output();
cout<<"*****在指定位置插入指定值*****"<<endl;
A.Insert(3,9);
A.Length();
A.Output();
cout<<"*****删除指定位置处的值并输出*****"<<endl;
A.Delete(2);
A.Length();
A.Output();
cout<<"*****删除链表中的重复值*****"<<endl;
A.Delete_Repeat();
A.Output();
cout<<"*****链表的合并*****"<<endl;
B.Create();
B.Output(); //创建新表B并输出
cout<<endl;
C=Merge(A,B);
C.Output(); //输出由A和B合并所得的表C
cout<<endl;
C.Destroy(); //销毁表C
C.Output(); //表C销毁后输出一张空表
return 0;
}