链表的基本操作:(不介绍,直接上代码)
先看一下最终界面:
代码:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
typedef int ElemType;
typedef struct Node{
ElemType data;
struct Node *next;
}Node, *LinkList;
void InitList(LinkList *L)
{
*L=(LinkList)malloc(sizeof(Node));
if(!(*L))
printf("存储分配失败\n");
(*L)->next=NULL;
}
void DestroyList(LinkList L)
{
LinkList p;
while(L)
{
p=L->next;
free(L);
L=p;
}
}
int ListLength(LinkList L)
{
LinkList p;
int i=0;
p=L->next;
while(p)
{
i++;
p=p->next;
}
return i;
}
int GetElem(LinkList L,int i,ElemType &e){
LinkList p;
p=L->next;
int j=1;
while(p&&j<i){
p=p->next;
++j;
}
e=p->data;
return e;
}
int GetElemLo(LinkList L,int i,ElemType &e){
LinkList p;
p=L->next;
int j=1;
while(p->data!=i&&j<=ListLength(L))
{
p=p->next;
++j;
}
e=j;
return e;
}
void FindPre(LinkList L,int x)
{
LinkList p;
p=L;
if(p->next->data==x)
{
printf("第一个元素没有前驱\n");
}
else{
while(p->next)
{
if(p->next->data==x)
{
printf("%d的前驱结点是:%d\n",x,p->data);
break;
}
else{
p=p->next;
}
}
}
}
void FindNext(LinkList L,int x)
{
LinkList p;
p=L->next;
while(p)
{
if(p->data==x)
{
printf("%d的后继结点是:%d\n",x,p->next->data);
break;
}
else
{
p=p->next;
}
if(p->next==NULL)
{
printf("最后一个元素没有后继\n");
break;
}
}
}
void LinkInset_L(LinkList &L,int i,ElemType e){
LinkList p;
p=L;
int j=0;
while(p&&j<i-1)
{
p=p->next;
++j;
}
if(!p||j>i-1)
printf("i小于1或者i大于表长加1\n");
LinkList s;
s=(LinkList)malloc(sizeof (Node));
s->data=e;
s->next=p->next;
p->next=s;
}
void ListDelete_L(LinkList &L,int i,ElemType &e){
LinkList p,q;
p=L;
int j=0;
while(p->next && j<i-1)
{
p=p->next;
++j;
}
if(!p->next ||j>i-1)
printf("删除位置不合理\n");
q=p->next;
p->next=q->next;
e=q->data;
free(q);
printf("已删除的元素是:%d\n",e);
}
void visit(ElemType e)
{
printf("%d,",e);
}
void ListTraverse(LinkList L)
{
LinkList p=L->next;
while(p)
{
visit(p->data);
p=p->next;
}
printf("\n");
}
void CreatListTail(LinkList *L,int n)
{
LinkList p,r;
int i;
srand(time(0));
*L=(LinkList)malloc(sizeof(Node));
r=*L;
for(i=0;i<n;i++)
{
p=(Node *)malloc(sizeof(Node));
p->data=rand()%100+1;
r->next=p;
r=p;
}
r->next=NULL;
}
int main()
{
LinkList L;
int opp;
printf("可执行的操作有:\n");
printf("1.初始化或重置链表\n");
printf("2.随机插入元素\n");
printf("3.显示链表中数据元素个数\n");
printf("4.输出所输入的链表元素\n");
printf("5.所指位序的元素值\n");
printf("6.链表已存在元素的位序\n");
printf("7.请输入元素,求直接前驱\n");
printf("8.请输入元素,求直接后继\n");
printf("9.在第i个位置插入元素\n");
printf("10.删除第i个元素\n");
printf("11.销毁链表\n");
printf("12.退出\n");
printf("\n");
printf("请输入你的选择:\n");
do{
scanf("%d",&opp);
switch(opp)
{
case 1:
{
InitList(&L);
printf("链表已初始化\n");
printf("下一步操作:");
break;
}
case 2:
{
int n;
printf("输入插入元素个数:");
scanf("%d",&n);
CreatListTail(&L,n);
printf("下一步操作:");
break;
}
case 3:
{
printf("链表中元素的个数是:%d\n",ListLength(L));
printf("下一步操作:");
break;
}
case 4:
{
ListTraverse(L);
printf("下一步操作:");
break;
}
case 5:
{
int m,e;
printf("输入要取元素的位置:");
scanf("%d",&m);
if(m>ListLength(L))
{
printf("输入有误\n");
}
else{
GetElem(L,m,e);
printf("该元素是:%d\n",e);}
printf("下一步操作:");
break;
}
case 6:
{
int i,e;
printf("输入要取的元素:");
scanf("%d",&i);
GetElemLo(L,i,e);
printf("该元素的位置是:%d\n",e);
printf("下一步操作:");
break;
}
case 7:
{
int x;
printf("要求哪个元素的前驱?");
scanf("%d",&x);
FindPre(L,x);
printf("下一步操作:");
break;
}
case 8:
{
int x;
printf("要求哪个元素的后继?");
scanf("%d",&x);
FindNext(L,x);
printf("下一步操作:");
break;
}
case 9:
{
int i,e;
printf("在哪个位置插入元素?");
scanf("%d",&i);
if(i>ListLength(L))
printf("输入有误\n");
else{
printf("插入的新元素是:");
scanf("%d",&e);
LinkInset_L(L,i,e);
printf("新链表:");
ListTraverse(L);
}
printf("下一步操作:");
break;
}
case 10:
{
int i,e;
printf("要删除哪个位置的元素?");
scanf("%d",&i);
if(i>ListLength(L))
printf("输入有误\n");
else{
ListDelete_L(L,i,e);
printf("新链表:");
ListTraverse(L);
}
printf("下一步操作:");
break;
}
case 11:
{
DestroyList(L);
printf("链表已销毁!\n");
printf("下一步操作:");
break;
}
case 12:
{
printf("谢谢使用\n");
break;
}
default:{
printf("输入错误,请重新输入\n");
break;}
}
}while(opp!=12);
return 0;
}