线性表的实现分为顺序存储实现和链式存储实现,本文将主要讲述链式存储,线性存储将在下一篇讲述。通过链式存储实现对线性表的各项操作,包括初始化、创建、获取特定位置上的元素、获取线性表长度、插入、删除、定位Locate、销毁、合并两个链表以及单链表的就地逆置。
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
typedef struct node{
int data;
struct node *next;
}linkList;
void initList(linkList*L)//初始化
{
L=(linkList*)malloc(sizeof(linkList));
L->next=NULL;
}
void creatList(linkList*L)//创建
{
linkList*s,*last;
int temp;
last=L;
while((temp=getchar())!='#')
{
s=(linkList*)malloc(sizeof(linkList));
s->data=temp-'0';
s->next=NULL;
last->next=s;
last=s;
}
}
void printList(linkList*L)//打印
{
linkList*p;
p=L->next;
while(p!=NULL)
{
printf("%4d",p->data);
p=p->next;
}
printf("\n");
}
void getElem(linkList*L, int n)//获取特定位置上的元素,n表示线性表位置
{
linkList *p;
p=L->next;
int i=1;
while (i<n)
{
p=p->next;
i++;
}
printf("该位置上的值是%d",p->data);
printf("\n");
}
int lengthList(linkList*L)//表的长度
{
linkList *p;
int num=0;
p=L->next;
while(p!=NULL)
{
num++;
p=p->next;
}
return num;
}
void insertList(linkList*L,int a,int n)//在特定位置n插入元素a
{
linkList *p,*q,*s;
int i=1;
p=L;
q=L->next;
while(i<n)
{
p=p->next;
q=q->next;
i++;
}
s=(linkList*)malloc(sizeof(linkList));
s->data=a;
s->next = q;
p->next = s;
}
void deleList(linkList*L,int n)//删除位置n上的元素
{
linkList *p,*q;
int i=1;
p=L;
q=L->next;
while(i<n)
{
p=p->next;
q=q->next;
i++;
}
p->next=q->next;
}
int locateElement(linkList*L,int a)//定位元素a在线性表中的位置
{
linkList *p;
int i=1;
p=L->next;
int k=1;
while(k==1)
{
if(p->data == a)
break;
else
{
p=p->next;
i++;
}
}
return i;
}
int ieverse(linkList *L)//单链表就地逆置
{
linkList *last=L->next;
linkList *first;
while(last->next)
{
first=L->next;
L->next=last->next;
last->next=L->next->next;
L->next->next=first;
}
return 1;
}
int countBack(linkList *L,int n)//链表中倒数第n个数据元素
{
linkList *p=L;
linkList *q=L;
int i=0;
while(p)
{
if(i<n)
i++;
else if(i==n)
{
q=q->next;
}
p=p->next;
}
return q->data;
}
void mergeList(linkList *M,linkList *N,linkList *L)//将两个有序表合并为一个
{
linkList *pa=M->next;
linkList *pb=N->next;
linkList *pc;
L=pc=M;
while((pa!= NULL)&&(pb!= NULL))
{
if(pa->data <= pb->data)
{
pc->next=pa;
pc=pa;
pa=pa->next;
}
else
{
pc->next=pb;
pc=pb;
pb=pb->next;
}
}
while(pa!= NULL)
{
pc->next=pa;
pc=pa;
pa=pa->next;
}
while(pb!= NULL)
{
pc->next=pb;
pc=pb;
pb=pb->next;
}
free(pb);
}
void destroyList(linkList*L)//销毁链表
{
if(L->next != NULL)
{
free(L->next);
L->next=NULL;
}
printf("Destroy List\n");
}
int main()
{
linkList *lList;
linkList *mList;
linkList *nList;
int i,n,m;
int a,b;
lList=(linkList*)malloc(sizeof(linkList));
mList=(linkList*)malloc(sizeof(linkList));
nList=(linkList*)malloc(sizeof(linkList));
initList(lList);
initList(mList);
initList(nList);
printf("输入一串数字以#结束\n");
creatList(lList);
printList(lList);
printf("长度是:%d\n",lengthList(lList));
printf("输入第二串数字以#结束\n");
getchar();
creatList(mList);
printList(mList);
printf("合并后的序列为:");
mergeList(lList,mList,nList);
printList(lList);
printf("倒数位置:");
scanf("%d",&n);
printf("该倒数位置上的数为:%d\n",countBack(lList,n));
ieverse(lList);
printf("逆置后的序列:");
printList(lList);
printf("输入要定位的元素\n");
getchar();
scanf("%d",&b);
printf("该元素在第%d个位置\n",locateElement(lList,b));
printf("输入要取得值的字符的位置\n");
scanf("%d",&m);
getElem(lList,m);
printf("输入要插入的字符及其位置\n");
getchar();
scanf("%d",&a);
scanf("%d",&n);
insertList(lList,a,n);
printList(lList);
printf("输入删除字符的位置\n");
scanf("%d",&i);
deleList(lList,i);
printList(lList);
destroyList(lList);
printList(lList);
return 0;
}