最完整的线性表应用 经测试可直接运行

有很多文章内容很丰富,但阅读的人很少,其之所以曲高和寡,大概是因为大部分的人看起来有难度。下面我总结了一下线性表的应用,以飨读者,为了方便初学者学习,每个程序都经过我调试运行,大家可阅之,运行之,有意见欢迎提出,欢迎留言。


基本的线性表有三种类型:顺序表、链表和静态链表,下面有三个程序,对应上述的三种链表。

顺序表:

/*------很简单的顺序线性表------*/ 

#include <stdio.h>
#include <stdlib.h>


#include<stdio.h>  //输入输出函数头文件
#include<stdlib.h>  //内存申请函数头文件
 
#define LIST_INIT_SIZE 10  //定义最初申请的内存的大小
#define LIST_INCREMENT 2  //每一次申请内存不足的时候扩展的大小
#define OVERFLOW false  //异常抛出返回值
#define ERROR false  //异常抛出返回值
#define INFEASIBLE false //异常抛出返回值
#define OK true  //程序正确执行抛出返回值
 
typedef int ElemType;  //别名声明,其实int可以用任意的名字代入
typedef bool Status;  //别名声明


typedef struct SqList
{
	ElemType *base;
	int len;
	int size;
}SqList;


void InitList(SqList &L)
{
       //初始条件:无
       L.base=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
       if(!L.base)
              exit(OVERFLOW);  //储存分配失败
       L.len=0;  //空表长度为0
       L.size=LIST_INIT_SIZE;  //初始储存容量
}

//删除节点后,后面的节点要移动 
//插入的位置是给出的 
Status InsertList(SqList &L, int i, ElemType e)
{
	ElemType *newbase,*q,*p;
	if(i<1||i>L.len+1) //插入的位置不合法 
		return ERROR;	
	if(L.len>=L.size)
	{
		if(!(newbase=(ElemType *)realloc(L.base,(L.size+LIST_INCREMENT)*sizeof(ElemType))))
			exit(OVERFLOW);
		L.base = newbase;
		L.size += LIST_INCREMENT;
	} 
	q = L.base+i-1;
	for(p=L.base+L.len-1;p>=q;--p)
		*(p+1) = *p;
	*q = e;
	++L.len;
	return OK;
}

//插入节点后,后面的节点要移动 
Status DeleteList(SqList &L, int i,ElemType &e)
{
	ElemType *p, *q;
	if(i<1||i>L.len)
		return ERROR;
	p = L.base+i-1;
	e = *p;
	q = L.base+L.len-1;
	for(++p;p<=q;++p)
	{
		*(p-1) = *p;		
	}
	L.len--;
	return OK;
}

int compare(int x,int y)
{
	return x!=y;
}

int LocateElem(SqList L, ElemType e, int type)
{
	ElemType *p;
	int i=1;
	p = L.base;
	while(i<=L.len&&compare(*p++,e))
		++i;
	if(i<L.len)
		return i;
	else
		return 0;
}

Status GetElem(SqList L,int i,ElemType &e)
{
	if(i<1||i>L.len)
		return ERROR;
	e = *(L.base+i-1);
	return OK;
}

/********************** 输入函数 **********************/
void InitListALL(SqList *L)   
{
       L->base=(ElemType*)malloc(LIST_INIT_SIZE*sizeof(ElemType));
       printf("enter the length:");
       scanf("%d",&L->len);
       for(int i=0;i<L->len;i++)
              scanf("%d",L->base+i);      
}

/********************** 输出函数 **********************/
void OutList(SqList *L)
{
       for(int i=0;i<L->len;i++) 
              printf("%d\t",*(L->base+i));
}

void Union(SqList &La, SqList Lb)
{
	int i,e;
	int len1 = La.len;
	int len2 = Lb.len;
	for (i=1;i<Lb.len;i++)
	{
		GetElem(Lb,i,e);
		if(!LocateElem(La,e,0))
			InsertList(La,++len1,e);
		
	}
}

//La 和 Lb 都是非递减排列 
void MergeList1(SqList La, SqList Lb, SqList &Lc)
{
	InitList(Lc);
	int i=1,j=1,k=0;
	ElemType ai,bj;
	while(i<=La.len&&j<=Lb.len)
	{
		GetElem(La,i,ai);
		GetElem(Lb,j,bj);
		if(ai<=bj)
		{
			InsertList(Lc,++k,ai);
			++i;
		}
		else
		{
			InsertList(Lc,++k,bj);
			++j;
		}		
	}
	while(i<=La.len)
	{
		GetElem(La,i++,ai);
		InsertList(Lc,++k,ai);
	}
	while(j<=La.len)
	{
		GetElem(Lb,j++,bj);
		InsertList(Lc,++k,bj);
	}	
} 

void MergeList2(SqList La,SqList Lb, SqList &Lc)
{
	int *pa,*pb,*pa_last,*pb_last,*pc;
	pa = La.base;
	pb = Lb.base;
	Lc.size = Lc.len =La.len+Lb.len;
	pc = Lc.base = (ElemType *)malloc(sizeof(ElemType)*Lc.size);
	if(!Lc.base)
		exit(OVERFLOW);
	pa_last = La.base + La.len-1;
	pb_last = Lb.base + Lb.len-1;
	while(pa<=pa_last&&pb<=pb_last)
	{
		if(*pa<=*pb)
			*pc++=*pa++;
		else
			*pc++=*pb++;
	}
	while(pa<=pa_last)
		*pc++=*pa++;
	while(pb<=pb_last)
		*pc++=*pb++;
} 

int main()
{
/********************** 函数声明区域 **********************/
       void InitList(SqList &L);
       Status ListInsert(SqList &L,int i,ElemType e);
       int ListLength(SqList L);
       int LocateElem(SqList L,ElemType e,int type);
       int compare(int x,int y);
       void Union(SqList &La,SqList Lb);
       void InitListALL(SqList *L);
       void OutList(SqList *L);
 
 
/********************** 程序执行区域 **********************/
       SqList La,Lb;  //定义顺序表La,Lb
       InitListALL(&La);  //建立A表
       InitListALL(&Lb);  //建立B表
       Union(La,Lb);  //把B表插入到A表中
       OutList(&La);  //输出A表
 
       return 0;
}



链表:




/********************** 声明部分 **********************/
#include<stdio.h>  //输入输出函数头文件
#include<stdlib.h>  //内存申请函数头文件
 
#define LIST_INIT_SIZE 10  //定义最初申请的内存的大小
#define LIST_INCREMENT 2  //每一次申请内存不足的时候扩展的大小
#define OVERFLOW false  //异常抛出返回值
#define ERROR false  //异常抛出返回值
#define INFEASIBLE false //异常抛出返回值
#define OK true  //程序正确执行抛出返回值
 
typedef int ElemType;  //别名声明,其实int可以用任意的名字代入
typedef bool Status;  //别名声明
int length;


typedef struct LNode
{
	ElemType data;
	struct LNode *next;
}LNode,*LinkList;

void InitListALL(LinkList &L)
{
	int i=0,e;
	int len; 
	LinkList p = L,s;
	printf("Please input the length:\n");
	scanf("%d",&len);
	for(i=0;i<len;i++)
	{
		//顺序链表的空间是一次性分配的,链式链表的空间是一个节点一个节点分配的 
		s = (LinkList)malloc(sizeof(LNode));
		scanf("%d",&e);
		s->data = e;
		p->next =s;
		p = s;
	}	
}

void OutList(LinkList &L)
{
	LinkList p = L->next;
	while(p!=NULL)
	{
		printf("%d",p->data);
		p = p->next;
	}
}

Status GetElem(LinkList L,int i,ElemType &e)
{
	int j = 1;
	LinkList p = L->next;
	while(p&&j<i)
	{
		p = p->next;
		j++;
	}
	if(!p||j>i)
		return ERROR;
	e = p->data;
	return OK;
		
}

//在第i个位置之前插入新节点e 
Status ListInsert(LinkList L, int i, ElemType e)
{
	int j = 0;
	LinkList p=L,s;
	while(p&&j<i-1)
	{
		p = p->next;
	} 
	if(p==NULL||j>i)
	{
		return ERROR;
	}
	s  = (LinkList)malloc(sizeof(LNode));
	s->data = e;
	s->next = p->next;
	p->next = s;
	return OK;
}

//这个函数还是很巧妙的
void MergeList(LinkList &La,LinkList &Lb,LinkList &Lc)
{
	LinkList pa,pb,pc;
	pa = La->next;
	pb = Lb->next;
	Lc = pc = La; //用La的头结点作为Lc的头节点
	while(pa&&pb)
	{
		if(pa->data<=pb->data)
		{
			pc->next = pa;
			pc = pa;
			pa = pa->next;
		}
		else
		{
			pc->next = pb;
			pc = pb;
			pb = pb->next;
		}
	}
	pc->next = pa?pa:pb;
	free(Lb);
}

int main()
{
	/********************** 函数声明区 **********************/
	void InitListALL(LinkList &L);
	void OutList(LinkList &L);
 
	/********************** 程序执行区 **********************/
       LinkList La,Lb,Lc;
       La=(LinkList)malloc(sizeof(LNode));
       Lb=(LinkList)malloc(sizeof(LNode));
       InitListALL(La);
       InitListALL(Lb);
       MergeList(La,Lb,Lc);
       OutList(Lc);
       return 0;
}




静态链表:

/********************** 声明部分 **********************/
#include<stdio.h>  //输入输出函数头文件
#include<stdlib.h>  //内存申请函数头文件
 
#define LIST_INIT_SIZE 10  //定义最初申请的内存的大小
#define LIST_INCREMENT 2  //每一次申请内存不足的时候扩展的大小
#define OVERFLOW false  //异常抛出返回值
#define ERROR false  //异常抛出返回值
#define INFEASIBLE false //异常抛出返回值
#define OK true  //程序正确执行抛出返回值
#define DestroyList ClearList  //两个函数实现的效果是一样的
#define MAX_SIZE 100  //最大的初始容量
typedef int ElemType;  //别名声明,其实int可以用任意的名字代入
typedef bool Status;  //别名声明
 
 
/********************** 结构体定义部分 **********************/

typedef struct{
	ElemType data;
	int cur;
}component,SLinkList[MAX_SIZE];

void InitList(SLinkList L)
{
	int i;
	L[MAX_SIZE-1].cur = 0; //L的最后一个元素只想表头 
	for(i=0;i<MAX_SIZE;i++)
	{
		L[i].cur = i+1;		
	} 
	L[MAX_SIZE-2].cur = 0;
}

int Length;

void InitListAll(SLinkList L)
{
	int i;
	printf("Please input the list you want\n");
	scanf("%d",&Length);
	for(i=1;i<=Length;i++)
		scanf("%d",&L[i].data);
}

void OutList(SLinkList L)
{
	int i;
	for(i=1;i<=Length;i++)
		printf("%d  ",L[i].data);
}

int LocateElem(SLinkList L,ElemType e)
{
	int i = L[0].cur;
	while(i&&L[i].data!=e)
 		i = L[i].cur;
	return i;
}

//判断链表是否为空, 
int IsEmpty(SLinkList L)
{
	int i;
	i = L[0].cur;
	if(L[0].cur)
		L[0].cur = L[i].cur;
	return i;
}

//回收指定下标的节点到备用链表中 
void Free(SLinkList L,int k)
{
	L[k].cur = L[0].cur;
	L[0].cur = k;
} 


/********************** 一次输入两个集合的元素,建立(A-B)U(B-A)的静态链表,S为其头指针。假设备用空间足够大,L[0]为其头指针 **********************/
void differecce(SLinkList &L,int &S)
{
       int r,m,n,i,j;
       InitList(L);  //初始化备用空间
       S=IsEmpty(L);  //生成S的头结点
       r=S;  //r指向S的当前最后节点
       printf("please enter the length of A and B:");
       scanf("%d %d",&m,&n);  //输入A和B的元素个数
       Length=m+n;
       for(j=1;j<=m;++j)  //建立A的链表
       {
              i=IsEmpty(L);  //分配节点
              scanf("%d",&L[i].data);  //输入A的元素值
              L[r].cur=i;  //插入到表尾
              r=i;
       }
       L[r].cur=0;  //尾节点的指针为空
       int b,p,k;
       for(j=1;j<=n;++j)  //依次输入B元素,若不在当前表中,则插入,否则删除
       {
              scanf("%d",&b); 
              p=S;
              k=L[S].cur;  //K指向集合A中第一个结点
              while(k!=L[r].cur&&L[k].data!=b)
              {//在当前表中查找
                     p=k;
                     k=L[k].cur;
              }
              if(k==L[r].cur)  //假如当前表中没有所说的这个元素
              {
                     i=IsEmpty(L);
                     L[i].data=b;
                     L[i].cur=L[r].cur;
                     L[i].cur=i;
              }
              else  //该元素已经在表中,删除之
              {
                     Length--;
                     L[p].cur=L[k].cur;
                     Free(L,k);
                     if(r==k)
                            r=p;
              }
       }
}


int main()
{
       /********************** 函数声明区 **********************/
       void InitList(SLinkList L);
       void InitListAll(SLinkList L);
       void OutList(SLinkList L);
       int LocateElem(SLinkList L,ElemType e);
       /********************** 程序执行区 **********************/
       int e,number;
       SLinkList L;
       InitList(L);
       InitListAll(L);
       printf("please enter the number you want:");
       scanf("%d",&e);
       number=LocateElem(L,e);
//     OutList(L);
       printf("the place is %d\n",number);
 
       return 0;
}
点赞