目录
结点的定义
重定义elemtype为新的数据类型,用法与int相同。这可以方便修改链表的数据域,只需要修改重定义即可。
typedef int elemtype;
下面是结点的基本结构
typedef struct m{
elemtype n;
struct m *next;
}list,*plist;
链表的操作
选择带头结点的链表方便对链表进行操作。
链表的前插
void createlist_h(plist &l,int n)//前插n个元素
{
//定义一个带头结点的链表
l=new list;
//将头指针的下一个节点指向空
l->next=NULL;
//定义一个指针t,初始值为空
plist t;
//定义一个变量i,初始值为0
int i;
//当i小于n时,循环执行以下操作
for(i=0;i<n;i++)
{
//定义一个新节点
t=new list;
//输入新节点的值
cin>>t->n;
//将新节点的指针指向头指针的下一个节点
t->next=l->next;
//将头指针的下一个节点指向新节点
l->next=t;
}
}
链表的后插
void createlist_r(plist &l,int n)//后插n个元素
{
//定义一个带头结点的链表
l=new list;
//将头指针的下一个节点指向空
l->next=NULL;
//定义一个指针t,初始值为l
plist t,r=l;
//定义一个变量i,初始值为0
int i;
//当i小于n时,循环执行以下操作
for(i=0;i<n;i++)
{
//定义一个新节点
t=new list;
//输入新节点的值
cin>>t->n;
//将新节点的指针指向r的下一个节点
t->next=r->next;
//将r的下一个节点指向新节点
r->next=t;
t->next=NULL;
r=t;
}
}
链表的初始化
bool initlist(plist &l)//初始化带头结点的链表
{
//定义一个带头结点的链表
l=new list;
//将头指针的下一个节点指向空
l->next=NULL;
//返回1
return 1;
}
链表的取值
bool getelem(plist l,int i,elemtype &e)//取出第i个结点的数据赋值给e
{
//定义变量j,初始值为1
int j=1;
//定义变量p,初始值为l的下一个节点
plist p=l->next;
//当j小于i,且p不为空时,循环执行以下操作
while(j<i&&p)
{
//将p指向下一个节点
p=p->next;
//将j加1
j++;
}
//当p为空,或者j大于i时,返回0
if(!p||j>i)return 0;
//将p的值赋给e
e=p->n;
//返回1
return 1;
}
链表的查找
plist locatelem(plist l,elemtype e)//查找值为e的结点
{
//定义一个指针p,初始值为l的下一个节点
plist p=l->next;
//当p不为空,且p的下一个节点为空时,循环执行以下操作
while(p&&!p->next)
p=p->next;
//返回p
return p;
}
链表的插入
bool listinsert(plist &l,int i,elemtype e)//在第i个结点前插入元素e
{
//定义一个指针p,初始值为l
plist p=l,t=new list;
//定义一个变量j,初始值为0
int j=0;
//当p不为空,且j小于i-1时,循环执行以下操作
while(p&&j<i-1)
{
//将p指向下一个节点
p=p->next;
//将j加1
j++;
}
if(!p&&j>i-1)return 0;
//当p为空,或者j大于i-1时,返回0
if(!p||j>i-1)return 0;
//将e赋给t
t->n=e;
//将t的指针指向p的下一个节点
t->next=p->next;
//将p的指针指向t
p->next=t;
//返回1
return 1;
}
链表的删除
bool listdelete(plist &l,int i)//删除第i个元素
{
//定义一个指针p,初始值为l
plist p=l,t;
//定义一个变量j,初始值为0
int j=0;
//当p的下一个节点不为空,且j小于i-1时,循环执行以下操作
while(p->next&&j<i-1)
{
//将p指向下一个节点
p=p->next;
//将j加1
j++;
}
//当p的下一个节点为空,或者j大于i-1时,返回0
if(!p->next||j>i-1)return 0;
//将p的指针指向下一个节点
t=p->next;
//将t的指针指向空
p->next=t->next;
//删除t
delete t;
//返回1
return 1;
}
删除链表中的重复元素
void ddlist(plist &l)//删除链表中的重复元素
{
//p指向当前节点,t指向下一个节点
plist p=l->next,t,t1,m;
while(p)
{
//t指向下一个节点
t=p->next;
//t1指向当前节点
t1=p;
//m指向当前节点
while(t)
{
//如果当前节点和下一个节点值相同
if(p->n==t->n)
{
//m指向下一个节点
m=t;
//t指向下一个节点
t=t->next;
//将当前节点指向下一个节点
t1->next=t;
//删除m指向的节点
delete m;
}
else {
//t1指向下一个节点
t1=t;
//t指向下一个节点
t=t->next;
}
}
//p指向下一个节点
p=p->next;
}
}
链表排序(升序和降序)
void sortlist(plist &l,int i)//链表排序
{
//定义一个指针p指向当前节点,初始值为l的下一个节点
plist p=l->next,t;
elemtype m;
if(i==0)//升序
while(p)
{
//定义一个指针t指向当前节点的下一个节点
t=p->next;
//当t不为空时,循环比较p和t的n值
while(t)
{
//如果p的n值大于t的n值,交换p和t的n值
if(p->n>t->n)
{
m=p->n;
p->n=t->n;
t->n=m;
}
else t=t->next;
//t指向t的下一个节点
}
//p指向p的下一个节点
p=p->next;
}
else if(i==1)//降序
while(p)
{
//定义一个指针t指向当前节点的下一个节点
t=p->next;
//当t不为空时,循环比较p和t的n值
while(t)
{
//如果p的n值小于t的n值,交换p和t的n值
if(p->n<t->n)
{
m=p->n;
p->n=t->n;
t->n=m;
}
else t=t->next;
//t指向t的下一个节点
}
//p指向p的下一个节点
p=p->next;
}
//显示链表
display(l);
}
合并两个升序的链表
plist mergelist(plist l,plist i)//合并两个升序的链表
{
// l: 第一个链表,i: 第二个链表
plist p=l->next,t=i->next,l1,l2;
// p: 第一个链表的指针,t: 第二个链表的指针,l1: 合并后的链表,l2: 合并后的链表的指针
initlist(l1);
// 初始化合并后的链表
l2=l1;
// l2: 合并后的链表的指针
while(p&&t)
{
// 当两个链表都不为空时
if(p->n<=t->n)
{
// 如果第一个链表的指针的值小于等于第二个链表的指针的值
l2->next=p;
// 将第一个链表的指针的值赋值给l2的指针的下一个值
p=p->next;
// 将第一个链表的指针的值指向下一个值
l2=l2->next;
// 将l2的指针的值指向下一个值
l2->next=NULL;
// 将l2的指针的值指向空
}
else
{
// 如果第一个链表的指针的值大于第二个链表的指针的值
l2->next=t;
// 将第二个链表的指针的值赋值给l2的指针的下一个值
t=t->next;
// 将第二个链表的指针的值指向下一个值
l2=l2->next;
// 将l2的指针的值指向下一个值
l2->next=NULL;
// 将l2的指针的值指向空
}
}
if(!p)l2->next=t;
// 如果第一个链表的指针为空,将第二个链表的指针的值赋值给l2的指针的下一个值
else l2->next=p;
// 将第一个链表的指针的值赋值给l2的指针的下一个值
return l1;
// 返回合并后的链表
}
反转链表
void imagelist(plist &l)//反转链表
{
plist p,t,t1,q=l->next;
while(q->next)q=q->next;//q指向最后一个结点,作为反转后的首元结点
while(1)
{
p=t=l->next;
while(t->next)//t指向当前链表的最后一个结点
{
t1=t;
t=t->next;
}
t->next=t1;//t之前倒数第二个结点
t1->next=NULL;//将t剔除
t=t->next;//t指向新链表的最后一个结点
if(t==p)break;
}
l->next=q;//l的头结点指向q
}
销毁链表
void breaklist(plist &l)//销毁链表
{
// l: 链表
plist p=l->next,t;
// p: 链表的指针,t: 链表的指针
while(p)
{
t=p;
p=p->next;
delete t;
// 删除链表的指针的值指向的值
}
delete l;
// 销毁链表
}
链表的遍历
void display(plist l)
{
//定义一个指针p,初始值为l的下一个节点
plist p=l->next;
//当p不为空时,循环执行以下操作
while(p)
{
//输出p的值
cout<<p->n<<" ";
//将p指向下一个节点
p=p->next;
}
//换行
cout<<endl;
}
链表的实现
我用项目的方法进行实现。项目的建立可以参考我的博客。
.h文件
#include<iostream>
using namespace std;
typedef int elemtype;
typedef struct m{
elemtype n;
struct m *next;
}list,*plist;
void menu();//菜单
void createlist_h(plist &l,int n);//前插n个元素
void createlist_r(plist &l,int n);//后插n个元素
bool initlist(plist &l);//初始化带头结点的链表
bool getelem(plist l,int i,elemtype &e);//取出第i个结点的数据赋值给e
plist locatelem(plist l,elemtype e);//查找值为e的结点
bool listinsert(plist &l,int i,elemtype e);//在第i个结点前插入元素e
bool listdelete(plist &l,int i);//删除第i个元素
void display(plist l);//显示链表
void ddlist(plist &l);//删除链表中的重复元素
void sortlist(plist &l,int i);//链表排序
plist mergelist(plist l,plist i);//合并两个升序的链表
void imagelist(plist &l);//反转链表
void breaklist(plist &l);//销毁链表
.cpp文件
#include"own.h"
void menu()//菜单
{
cout<<"1.取值 2.查找 3.插入 4.删除"<<endl;
cout<<"5.显示元素 6.删除重复元素 7.排序"<<endl;
cout<<"8.合并两个升序的链表 9.反转链表 -1.退出"<<endl;
cout<<"请输入:"<<endl;
}
void createlist_h(plist &l,int n)//前插n个元素
{
//定义一个带头结点的链表
l=new list;
//将头指针的下一个节点指向空
l->next=NULL;
//定义一个指针t,初始值为空
plist t;
//定义一个变量i,初始值为0
int i;
//当i小于n时,循环执行以下操作
for(i=0;i<n;i++)
{
//定义一个新节点
t=new list;
//输入新节点的值
cin>>t->n;
//将新节点的指针指向头指针的下一个节点
t->next=l->next;
//将头指针的下一个节点指向新节点
l->next=t;
}
}
void createlist_r(plist &l,int n)//后插n个元素
{
//定义一个带头结点的链表
l=new list;
//将头指针的下一个节点指向空
l->next=NULL;
//定义一个指针t,初始值为l
plist t,r=l;
//定义一个变量i,初始值为0
int i;
//当i小于n时,循环执行以下操作
for(i=0;i<n;i++)
{
//定义一个新节点
t=new list;
//输入新节点的值
cin>>t->n;
//将新节点的指针指向r的下一个节点
t->next=r->next;
//将r的下一个节点指向新节点
r->next=t;
t->next=NULL;
r=t;
}
}
bool initlist(plist &l)//初始化带头结点的链表
{
//定义一个带头结点的链表
l=new list;
//将头指针的下一个节点指向空
l->next=NULL;
//返回1
return 1;
}
bool getelem(plist l,int i,elemtype &e)//取出第i个结点的数据赋值给e
{
//定义变量j,初始值为1
int j=1;
//定义变量p,初始值为l的下一个节点
plist p=l->next;
//当j小于i,且p不为空时,循环执行以下操作
while(j<i&&p)
{
//将p指向下一个节点
p=p->next;
//将j加1
j++;
}
//当p为空,或者j大于i时,返回0
if(!p||j>i)return 0;
//将p的值赋给e
e=p->n;
//返回1
return 1;
}
plist locatelem(plist l,elemtype e)//查找值为e的结点
{
//定义一个指针p,初始值为l的下一个节点
plist p=l->next;
//当p不为空,且p的下一个节点为空时,循环执行以下操作
while(p&&!p->next)
p=p->next;
//返回p
return p;
}
bool listinsert(plist &l,int i,elemtype e)//在第i个结点前插入元素e
{
//定义一个指针p,初始值为l
plist p=l,t=new list;
//定义一个变量j,初始值为0
int j=0;
//当p不为空,且j小于i-1时,循环执行以下操作
while(p&&j<i-1)
{
//将p指向下一个节点
p=p->next;
//将j加1
j++;
}
if(!p&&j>i-1)return 0;
//当p为空,或者j大于i-1时,返回0
if(!p||j>i-1)return 0;
//将e赋给t
t->n=e;
//将t的指针指向p的下一个节点
t->next=p->next;
//将p的指针指向t
p->next=t;
//返回1
return 1;
}
bool listdelete(plist &l,int i)//删除第i个元素
{
//定义一个指针p,初始值为l
plist p=l,t;
//定义一个变量j,初始值为0
int j=0;
//当p的下一个节点不为空,且j小于i-1时,循环执行以下操作
while(p->next&&j<i-1)
{
//将p指向下一个节点
p=p->next;
//将j加1
j++;
}
//当p的下一个节点为空,或者j大于i-1时,返回0
if(!p->next||j>i-1)return 0;
//将p的指针指向下一个节点
t=p->next;
//将t的指针指向空
p->next=t->next;
//删除t
delete t;
//返回1
return 1;
}
void display(plist l)
{
cout<<"该链表为:";
//定义一个指针p,初始值为l的下一个节点
plist p=l->next;
//当p不为空时,循环执行以下操作
while(p)
{
//输出p的值
cout<<p->n<<" ";
//将p指向下一个节点
p=p->next;
}
//换行
cout<<endl;
}
void ddlist(plist &l)//删除链表中的重复元素
{
//p指向当前节点,t指向下一个节点
plist p=l->next,t,t1,m;
while(p)
{
//t指向下一个节点
t=p->next;
//t1指向当前节点
t1=p;
//m指向当前节点
while(t)
{
//如果当前节点和下一个节点值相同
if(p->n==t->n)
{
//m指向下一个节点
m=t;
//t指向下一个节点
t=t->next;
//将当前节点指向下一个节点
t1->next=t;
//删除m指向的节点
delete m;
}
else {
//t1指向下一个节点
t1=t;
//t指向下一个节点
t=t->next;
}
}
//p指向下一个节点
p=p->next;
}
}
void sortlist(plist &l,int i)//链表排序
{
//定义一个指针p指向当前节点,初始值为l的下一个节点
plist p=l->next,t;
elemtype m;
if(i==0)//升序
while(p)
{
//定义一个指针t指向当前节点的下一个节点
t=p->next;
//当t不为空时,循环比较p和t的n值
while(t)
{
//如果p的n值大于t的n值,交换p和t的n值
if(p->n>t->n)
{
m=p->n;
p->n=t->n;
t->n=m;
}
else t=t->next;
//t指向t的下一个节点
}
//p指向p的下一个节点
p=p->next;
}
else if(i==1)//降序
while(p)
{
//定义一个指针t指向当前节点的下一个节点
t=p->next;
//当t不为空时,循环比较p和t的n值
while(t)
{
//如果p的n值小于t的n值,交换p和t的n值
if(p->n<t->n)
{
m=p->n;
p->n=t->n;
t->n=m;
}
else t=t->next;
//t指向t的下一个节点
}
//p指向p的下一个节点
p=p->next;
}
//显示链表
display(l);
}
plist mergelist(plist l,plist i)//合并两个升序的链表
{
// l: 第一个链表,i: 第二个链表
plist p=l->next,t=i->next,l1,l2;
// p: 第一个链表的指针,t: 第二个链表的指针,l1: 合并后的链表,l2: 合并后的链表的指针
initlist(l1);
// 初始化合并后的链表
l2=l1;
// l2: 合并后的链表的指针
while(p&&t)
{
// 当两个链表都不为空时
if(p->n<=t->n)
{
// 如果第一个链表的指针的值小于等于第二个链表的指针的值
l2->next=p;
// 将第一个链表的指针的值赋值给l2的指针的下一个值
p=p->next;
// 将第一个链表的指针的值指向下一个值
l2=l2->next;
// 将l2的指针的值指向下一个值
l2->next=NULL;
// 将l2的指针的值指向空
}
else
{
// 如果第一个链表的指针的值大于第二个链表的指针的值
l2->next=t;
// 将第二个链表的指针的值赋值给l2的指针的下一个值
t=t->next;
// 将第二个链表的指针的值指向下一个值
l2=l2->next;
// 将l2的指针的值指向下一个值
l2->next=NULL;
// 将l2的指针的值指向空
}
}
if(!p)l2->next=t;
// 如果第一个链表的指针为空,将第二个链表的指针的值赋值给l2的指针的下一个值
else l2->next=p;
// 将第一个链表的指针的值赋值给l2的指针的下一个值
return l1;
// 返回合并后的链表
}
void imagelist(plist &l)//反转链表
{
plist p,t,t1,q=l->next;
while(q->next)q=q->next;//q指向最后一个结点,作为反转后的首元结点
while(1)
{
p=t=l->next;
while(t->next)//t指向当前链表的最后一个结点
{
t1=t;
t=t->next;
}
t->next=t1;//t之前倒数第二个结点
t1->next=NULL;//将t剔除
t=t->next;//t指向新链表的最后一个结点
if(t==p)break;
}
l->next=q;//l的头结点指向q
}
void breaklist(plist &l)//销毁链表
{
// l: 链表
plist p=l->next,t;
// p: 链表的指针,t: 链表的指针
while(p)
{
t=p;
p=p->next;
delete t;
// 删除链表的指针的值指向的值
}
delete l;
// 销毁链表
}
main.cpp文件
#include"own.h"
int main()
{
//定义变量
int n,a;
plist h,h1;
//循环输入
while(1)
{
cout<<"1.前插 2.后插"<<endl;
cout<<"请输入:";
cin>>a;
cout<<"请输入元素个数:";
cin>>n;
cout<<"请输入元素:";
//根据输入的选项,调用不同的函数
if(a==1){
createlist_h(h,n);
break;
}
else if(a==2){
createlist_r(h,n);
break;
}
}
//循环输出
while(1)
{
menu();
cin>>a;
//根据输入的选项,调用不同的函数
if(a==1)
{
elemtype t;
int m;
cout<<"输入取出的元素位置:";
cin>>m;
//调用函数,获取元素
if(getelem(h,m,t))
cout<<"该元素为:"<<t<<endl;
else cout<<"ERROR"<<endl;
}
else if(a==2)
{
plist t;
elemtype m;
cout<<"输入要查找元素:";
cin>>m;
//调用函数,查找元素
t=locatelem(h,m);
if(t==NULL)cout<<"ERROR"<<endl;
else cout<<"成功"<<endl;
}
else if(a==3)
{
int m;
elemtype t;
cout<<"输入插入的位置和数据";
cin>>m>>t;
//调用函数,插入元素
if(listinsert(h,m,t))
cout<<"插入成功"<<endl;
else cout<<"ERROR"<<endl;
}
else if(a==4)
{
int m;
cout<<"请输入删除的元素位置:";
cin>>m;
//调用函数,删除元素
if(listdelete(h,m))
cout<<"删除成功"<<endl;
else cout<<"ERROR"<<endl;
}
//调用函数,显示链表
if(a==5)display(h);
if(a==6)
{
ddlist(h);
display(h);
}
if(a==7)
{
int i;
cout<<"0.升序 1.降序"<<endl;
cin>>i;
sortlist(h,i);
}
if(a==8)
{
plist t;
initlist(h1);
cout<<"h1尾插五个:";
createlist_r(h1,5);
h=mergelist(h,h1);
display(h);
}
if(a==9)
{
imagelist(h);
display(h);
}
else if(a==-1)break;
}
if(h)breaklist(h);
if(h1)breaklist(h1);
}
运行试例
欢迎指正
感谢阅读本文,如果您有任何问题或建议,请随时与我联系。祝愿您编程愉快,继续前进!