基于C语言实现的链表
程序代码:
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define ERROR 0
#define OK 1
#define True 1
#define False 0
#define OVERFLOW -2
typedef int ElemType; /*定义链表元素的类型*/
typedef int Status; /*定义函数的类型,其值是函数结果状态代码*/
typedef struct LNode{ /*线性表的单链表存储*/
ElemType data;
struct LNode *next;
}LNode,*LinkList;
void CreateList1_L(LinkList &L, int n); /* 带头结点的单链表的建立(前插法) */
void CreateList2_L(LinkList &L, int n); /* 带头结点的单链表的建立(尾插法) */
void ClearList_L(LinkList &L);//清空线性表L
void DestroyList_L(LinkList &L); /* 销毁单链表 */
void PrintList_L(LinkList L); /*输出带头结点单链表的所有元素*/
Status InsertList_L(LinkList &L,int i,ElemType e);在带头结点的单链表L中第i个位置前插入元素e
Status DeleteList_L(LinkList &L, int i, ElemType &e);//删除第i个元素,并由e返回其值
Status GetElem_L(LinkList L,int i,ElemType &e); //获取第i个元素值
LNode *LocateELem1_L(LinkList L,ElemType e); //在线性表L中查找值为e的数据元素,返回L中值为e的数据元素的地址,查找失败返回NULL
int LocateELem2_L (LinkList L,ElemType e); //在线性表L中查找值为e的数据元素,返回L中值为e的数据元素的位置序号,查找失败返回0
int ListLength_L(LinkList L);//获取表长
Status ListEmpty_L(LinkList L);//判断线性表L是否为空
void CreateList1_L(LinkList &L, int n)/* 带头结点的单链表的建立(前插法) */
{//输入n个元素的值,建立带表头结点的单链表L。
LNode *p;
L=(LNode *)malloc(sizeof(LNode));
L->next=NULL;//建立一个带头结点的单链表
printf("请输入n个数(前插法):\n");
for(int i=n;i>=1;--i)
{
p=(LNode *)malloc(sizeof(LNode)); //生成新节点
scanf("%d",&p->data);//输入里面不能有空格,否则总会多一个数等待输入------------------------
p->next=NULL;
p->next=L->next;
L->next=p; //插入到表头
}
}/*CreateList1_L*/
void CreateList2_L(LinkList &L, int n)/* 单链表的建立(尾插法) */
{
LNode *p,*q;
L=(LNode *)malloc(sizeof(LNode));
L->next=NULL;
q=L;
printf("请输入n个数(尾插法):\n");
for(int i=1;i<=n;i++)
{
p=(LNode *)malloc(sizeof(LNode));
scanf("%d",&p->data);
p->next=NULL;
q->next=p; //不能弄反,否则无数据输出--------------------
q=p;
}
}/*CreateList2_L*/
void ClearList_L(LinkList &L)//清空线性表L
{//删除线性表L所有数据元素结点,使其成为空表
LNode *p;
if(L)
{
p=L;
while(p)
p=NULL;
}
}/*ClearList_L*/
void DestroyList_L(LinkList &L) /* 销毁单链表 */
{//释放线性表L所有结点的存储空间
LNode *p,*q;
p=L;
while(p->next)
{
q=p->next;
delete p;
p=q; //不能弄反,否则程序终止-------------------------
}
L=NULL;
}/*DestroyList_L*/
void PrintList_L(LinkList L)//输出带头结点单链表的所有元素
{
LNode *p;
int i,e;
p=L->next;
while(p)
{
printf("%d ",p->data);
p=p->next;
}
printf("链表已输出完毕...");
}/*PrintList_L*/
Status InsertList_L(LinkList &L,int i,ElemType e)//在带头结点的单链表L中第i个位置前插入元素e
{
LNode *p,*q;
p=L;
int j=0;
while(p && j<i-1)
{
p=p->next;
j++;
}
if(!p||j>i-1)return ERROR;
q=(LNode *)malloc(sizeof(LNode));
q->data=e;
q->next=p->next;
p->next=q;
return OK;
}/*InsertList_L*/
Status DeleteList_L(LinkList &L, int i, ElemType &e)//删除第i个元素,并由e返回其值
{
LNode *p,*q;
int j=0; //用于记录表长
p=L;
while(p->next && j<i-1)
{
p=p->next;
j++;
}
if(!(p->next) || j>i-1) return ERROR;
q=p->next;
p->next=q->next; //不能弄反,否则date和next无效---------------------------------
e=q->data;
free(q);
return OK;
}/*DeleteList_L*/
Status GetElem_L(LinkList L,int i,ElemType &e)//获取第i个元素值
{
LNode *p=L;
for(int j=1;j<=i;j++)
{
p=p->next;
}
if(p)
e=p->data;
return OK;
}/*GetElem*/
LNode *LocateELem1_L(LinkList L,ElemType e) //在线性表L中查找值为e的数据元素,返回L中值为e的数据元素的地址,查找失败返回NULL
{ //返回L中值为e的数据元素的地址,查找失败返回NULL
LNode *p;
p=L;
while(p&&p->data!=e)
p=p->next;
return p;
}//LocateELem1_L
int LocateELem2_L (LinkList L,ElemType e) //在线性表L中查找值为e的数据元素,返回L中值为e的数据元素的位置序号,查找失败返回0
{ //返回L中值为e的数据元素的位置序号,查找失败返回0
LNode *p;
int j=0; //用于记录表长
p=L;
while(p && p->data!=e)
{
p=p->next;
j++;
}
return j;
} //LocateELem2_L
int ListLength_L(LinkList L)//获取表长
{
LNode *p;
int j=0; //用于获取表长
p=L;
while(p->next)
{
p=p->next;
j++;
}
return j;
}
Status ListEmpty_L(LinkList L)//判断线性表L是否为空
{
if(L->next==NULL)return true;
else return false;
}
int main(){
int n,i;
ElemType e;
LinkList L=NULL; /*定义指向单链表的指针*/
printf("please input n:"); /*输入单链表的元素个数*/
scanf("%d",&n);
if(n>0){
printf("\n前插法建立带头结点的单链表......\n");
printf("\n1-建立链表:\n");
CreateList1_L(L,n);
printf("\n2-输出链表:\n");
PrintList_L(L);
printf("链表表长:%d\n",ListLength_L(L));
printf("\n");
printf("\n3-获取第i个元素值:\n");
printf("input i=");
scanf("%d",&i);
if(GetElem_L(L,i,e)) printf("第%d个元素值为%d\n",i,e);
else printf("not exists\n");
printf("\n4-查找L中值为e的数据元素的位置序号:\n");
printf("input e=");
scanf("%d",&e);
i=LocateELem2_L(L,e);
printf("\n");
if(i!=0) printf("值为%d的数据元素的位置序号为%d\n",e,i);
else printf("查找失败\n");
printf("\n5-在单链表L中第i个位置前插入元素e:\n");
printf("input i=");
scanf("%d",&i);
printf("input e=");
scanf("%d",&e);
if(InsertList_L(L,i,e))
{
printf("输出链表:\n");
PrintList_L(L);
printf("\n");
printf("链表表长:%d\n",ListLength_L(L));
printf("\n");
}
else printf("插入位置不合理\n");
printf("\n6-删除单链表L中第i个位置的元素:\n");
printf("input i=");
scanf("%d",&i);
if(DeleteList_L(L,i,e))
{
printf("输出链表:\n");
PrintList_L(L);
printf("链表表长:%d\n",ListLength_L(L));
if(ListEmpty_L(L)) printf("链表L为空\n");
else printf("链表L不空\n");
printf("\n");
}
else printf("删除位置不合理\n");
printf("\n清空单链表......\n");
ClearList_L(L); //清空单链表L
printf("链表表长:%d\n",ListLength_L(L));
if(ListEmpty_L(L)) printf("链表L为空\n");
else printf("链表L不空\n");
printf("\n");
printf("\n销毁单链表......\n");
DestroyList_L(L);
printf("\n");
printf("\n");
printf("\n尾插法建立带头结点的单链表......\n");
printf("\n1-建立链表:\n");
CreateList2_L(L,n);
printf("\n2-输出链表:\n");
PrintList_L(L);
}
else printf("ERROR");
printf("\n");
return 0;
}
运行结果: