链表,一种重要的数据结构。它与数组不同,数组是分配一段连续的存储空间;而链表则是动态地分配离散空间,并用指针串联。
下面是链表的基本操作。
链表的插入
注意:第一步和第二步的顺序不能颠倒。
Status LinkListInsert(LinkList L,int i,ElemType e)///链表的插入操作
{
LNode *p,*s;
int j;
p=L;
j=0;
while(p->next!=NULL&&j<i-1)
{
p=p->next;
++j;
}
if(!p||j>i-1) return ERROR;
s=(LNode *)malloc(sizeof(LNode));
s->data=e;
s->next=p->next;
p->next=s;
return OK;
}
链表的删除
Status LinkListDelete(LinkList L,int i,ElemType *e)///链表的删除操作
{
LNode *p,*q;
int j;
p=L;
j=0;
while(p->next!=NULL&&j<i-1)
{
p=p->next;///寻找第i个结点,令p指向其前驱
j++;
}///j<i-1 ---> p找到要删除结点的上一个结点
if(!p||j>i-1) return ERROR;
///删除q结点
q=p->next;
p->next=q->next;
*e=q->data;
free(q);
return OK;
}
链表的基本操作
#include "stdio.h"
#include "stdlib.h"
#define OK 1
#define ERROR 0
typedef int ElemType;
typedef int Status;
typedef struct LNode
{
ElemType data;
ElemType length;
struct LNode *next;
}LNode,*LinkList;
Status LinkListInit(LinkList *L)///初始化操作
{
*L=(LinkList)malloc(sizeof(LNode));///创建一个带头结点的单链表
(*L)->next=NULL;
return OK;
}
Status InputLinkList(LinkList L,int n)///头插法
{
LNode *p;
int i;
for(i=0;i<n;i++)
{
p=(LNode *)malloc(sizeof(LNode));
scanf("%d",&p->data);
p->next=L->next;///头插法插入到表头
L->next=p;
}
return OK;
}
void OutputLinkList(LinkList L)///输出
{
LNode *p;
p=L;
while(p->next!=NULL)
{
p=p->next;
printf("%d ",p->data);
}
printf("\n");
}
int LinkListLength(LinkList L)///求长度
{
LNode *p;
int count=0;
p=L;
while(p->next!=NULL)
{
p=p->next;
count++;
}
return count;
}
Status GetElem_L(LinkList L,int i,ElemType *e)///获取元素
{
LNode *p;
int j;
p=L->next;
j=1;
if(i<1) return ERROR;
while(p!=NULL&&j<i)
{
p=p->next;
++j;
}
/*
p=L;///第二种方式
j=0;
if(i<1) return ERROR;
while(p->next!=NULL&&j<i)
{
p=p->next;
++j;
}
*/
if(!p) return ERROR;
*e=p->data;
return OK;
}
Status ClearLinkList(LinkList L)///清空链表
{
LNode *p,*q;
p=L->next;
L->next=NULL;
while(p!=NULL)
{
q=p->next;
free(p);
p=q;
}
return OK;
}
Status LinkListInsert(LinkList L,int i,ElemType e)///链表的插入操作
{
LNode *p,*s;
int j;
p=L;
j=0;
while(p->next!=NULL&&j<i-1)
{
p=p->next;
++j;
}
if(!p||j>i-1) return ERROR;
s=(LNode *)malloc(sizeof(LNode));
s->data=e;
s->next=p->next;
p->next=s;
return OK;
}
Status LinkListDelete(LinkList L,int i,ElemType *e)///链表的删除操作
{
LNode *p,*q;
int j;
p=L;
j=0;
while(p->next!=NULL&&j<i-1)
{
p=p->next;///寻找第i个结点,令p指向其前驱
j++;
}///j<i-1 ---> p找到要删除结点的上一个结点
if(!p||j>i-1) return ERROR;
///删除q结点
q=p->next;
p->next=q->next;
*e=q->data;
free(q);
return OK;
}
Status ReverseLinkList(LinkList L)///链表的反转操作
{
LNode *p,*q;
p=L->next;
L->next=NULL;
while(q)
{
q=p->next;
p->next=L->next;
L->next=p;
p=q;
}
return OK;
}
void main()
{
LinkList L;
int choice=1;
int n;
if(LinkListInit(&L)==OK)
printf("OK\n");
else
printf("ERROR\n");
while(choice!=0)
{
system("cls");
printf("1.LinkListInit 2.InputLinkList 3.OutputLinkList\n");
printf("4.LinkListLength 5.GetElem_L 6.ClearLinkList\n");
printf("7.LinkListInsert 8.LinkListDelete 9.ReverseLinkList 0.exit\n");
printf("please input your choice:\n");
scanf("%d",&choice);
switch(choice)
{
case 1:
{
if(LinkListInit(&L)==OK)
printf("链表初始化成功!\n");
break;
}
case 2:
{
printf("请输入放入链表中的元素的总数:\n");
scanf("%d",&n);
printf("请输入第%d个元素:\n",n);
if(InputLinkList(L,n)==OK)
printf("放入元素成功!\n");
break;
}
case 3:
{
OutputLinkList(L);
break;
}
case 4:
{
int len;
len=LinkListLength(L);
printf("链表的长度为: %d\n",len);
break;
}
case 5:
{
ElemType e;
int position;
printf("请输入您想获取第几个位置对应的值:\n");
scanf("%d",&position);
if(GetElem_L(L,position,&e)==OK)
printf("第%d个位置的元素为:%d\n",position,e);
else
printf("没有找到!\n");
break;
}
case 6:
{
if(ClearLinkList(L)==OK)
printf("成功清空链表!\n");
break;
}
case 7:
{
ElemType e;
int i;
printf("请输入要插入的元素:\n");
scanf("%d",&e);
printf("请输入要插入的位置:\n");
scanf("%d",&i);
if(LinkListInsert(L,i,e)==OK)
{
OutputLinkList(L);
}
break;
}
case 8:
{
ElemType e;
int i;
printf("请输入要删除元素的位置:\n");
scanf("%d",&i);
if(LinkListDelete(L,i,&e)==OK)
{
printf("成功删除元素:%d!\n",e);
OutputLinkList(L);
}
else
{
printf("删除%d失败!\n",i);
printf("您要删除的元素在第%d个位置\n",i);
}
break;
}
case 9:
{
if(ReverseLinkList(L)==OK)
{
printf("反转链表成功!反转后的链表为:\n");
OutputLinkList(L);
}
break;
}
}
system("pause");
}
}