You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

197 lines
3.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include<iostream>
using namespace std;
#include<stdlib.h>
#define OK 1
#define ERROR 0
typedef int status;
typedef int ElemType;
//用结构体定义一个单链表
typedef struct LNode
{
ElemType data; //存储链表的数据元素
struct LNode *next; //定义一个结构体指针用来指向下一个链表结点的地址
}LNode,*Linklist; //这里定义的 Linklist ==LNode *;
//---------单链表的基本操作------------
//一、单链表的初始化以及正序输入
status Initlist(Linklist &L,int n)
{
Linklist q,p;
L=(Linklist)malloc(sizeof(LNode)); //为单链表分配头结点,但注意头结点不是链表的第一个结点
L->next=NULL; //头结点的指针域指向第一个结点的地址
q=L; //让q指向链表的尾指针
cout<<"请输入单链表的元素:"<<endl;
for(int i=0;i<n;i++)
{
p=(Linklist)malloc(sizeof(LNode));
cin>>p->data;
q->next=p; //将q的指针域指向p
q=p; //让p成为新的q
}
q->next=NULL;
return OK;
}
//二、单链表的插入
status Insertlist(Linklist &L,int i,ElemType e)
{
Linklist p,s;
int j=0;
p=L;
while(p&&j<i-1)
{
p=p->next;
j++;
} //此while循环用于查找插入位置的前一个结点
if(!p||j>i-1)
return ERROR; //此if语句判断查找是否失败
s=(Linklist)malloc(sizeof(LNode)); //为插入的数据分配一个结点
if(!s)
return ERROR;
s->data=e;
s->next=p->next; //将p的指针域传给s的指针域
p->next=s; //然后将p的指针域指向s结点
return OK;
}
//三、单链表的删除
status Deletelist(Linklist &L,int i,ElemType &e)
{
Linklist p,q;
int j=0;
p=L;
while(p&&j<i-1)
{
p=p->next;
j++;
}
if(!(p->next)||j>i-1) //当如果p的下一个结点为空时则删除错误
return ERROR;
q=p->next; //将要删除的结点用q指向
e=q->data; //用e返回删除结点的元素
p->next=q->next; //将q的指针域传给p;
free(q);
return OK;
}
//四、单链表的查找
status GetElem(Linklist L,int e,int &i)
{
Linklist p=L->next;
if(p==NULL)
return ERROR;
i=1;
while(p)
{
if(p->data==e)
{
return i; //如果在链表中找到该元素,则输出其位序
}
p=p->next; //否则继续下移查找
i++;
}
}
//五、单链表的输出
status Printf(Linklist L)
{
Linklist p;
p=L->next; //让p表示单链表的第一个结点
while(p)
{
cout<<p->data<<" ";
p=p->next; //输出第一个结点数据后p后移一位
}
cout<<endl;
return OK;
}
//单链表的逆置(头插法)
status Reservelist(Linklist &L)
{
Linklist p,q; //定义两个指针p是当头结点与第一个结点断开时而设立的指针指向第一个结点
p=L->next; //而q的作用也是与p类似。
L->next=NULL; //将头结点与第一个结点的链接断开
while(p)
{
q=p->next; //q是为了指向剩余未逆置的元素地址
p->next=L->next;
L->next=p; //以上两条语句是将第一个结点逆置插入
p=q; //然后将q赋给p;
}
return OK;
}
//单链表的清空
status Clearlist(Linklist &L)
{
Linklist p,q;
p=L->next;
while(p)
{
p=q;
q=p->next; //设立一个q指向剩下的结点之后一个一个清空。
free(p);
}
L->next=NULL;
cout<<"此链表已清空"<<endl;
return OK;
}
//单链表的销毁
status Destroylist(Linklist &L)
{
Linklist p;
while(L)
{
p=L;
L=L->next;
free(p);
}
cout<<"此链表已销毁。"<<endl;
return OK;
}
int main()
{
Linklist L;
int n,i;
ElemType e;
cout<<"请输入单链表的长度:"<<endl;
cin>>n;
Initlist(L,n);
cout<<"单链表为:"<<endl;
Printf(L);
cout<<"请输入要插入第几个结点、插入的元素:"<<endl;
cin>>i>>e;
Insertlist(L,i,e);
cout<<"插入元素后单链表为:"<<endl;
Printf(L);
cout<<"请输入要删除的结点位置:"<<endl;
cin>>i;
Deletelist(L,i,e);
cout<<"删除的元素为:"<<e<<endl;
cout<<"删除元素后单链表为:"<<endl;
Printf(L);
cout<<"请输入要查找的结点元素:";
cin>>e;
GetElem(L,e,i);
cout<<e<<"对应的结点位置为:"<<i<<endl;
cout<<endl;
cout<<"单链表逆置后输出为:"<<endl;
Reservelist(L);
Printf(L);
Clearlist(L);
Destroylist(L);
return OK;
}