线性表(持续更新中)


This article is mainly about my organization of the data structure. If you get any problems,you can ask me on GitHub.

1 存储方式

1.1 顺序表示

#include<stdio.h>
#include<stdlib.h>
#define addsize 10
#define initsize 100
#define ok 1
#define OVERFLOW 0
#define ERROR 0
typedef int elemtype;
typedef int status;
typedef struct list
{
	elemtype *elem;
	int length;
	int size;
}sqlist;


status InitList(sqlist *l)
 {
	l->elem=(elemtype *)malloc(initsize*sizeof(elemtype));
	if(!(l->elem)) exit(OVERFLOW) ;
	l->length=0;
	l->size=initsize;
	return 0;
}

status ListInsert(sqlist *l,int i,elemtype e)
{
	elemtype *newelem,*p,*q;
	if((i>l->length+1)||(i<1)) return ERROR;
	if((l->length)>=(l->size))  
	{
		newelem=(elemtype *)realloc(l->elem,(l->size+addsize)*sizeof(elemtype));
		if(!newelem) exit(OVERFLOW);
		l->elem=newelem;
		l->size+=addsize;			
	}
	q=&(l->elem[i-1]);
	p=&(l->elem[l->length]);
	for(p;p>q;p--)
	*p=*(p-1);
	*p=e;
	l->length+=1;
	return 0;
 } 

status fun1(elemtype p,elemtype e)
 {
 	if(p%10==e) return 1;
 	else return 0;
  } 
 
 status LocateElem(sqlist l,elemtype e,status (*fun1)(elemtype,elemtype)) 
 {
 	int i=1;
 	elemtype *p=(l.elem);
 	while((i<=l.length)&&!(*fun1)(*p++,e)) ++i;
 	if(i<=l.length) return i;
 	else return 0;
 }
 
 status ListDelete(sqlist *l,int i,elemtype *e)
 {
 	elemtype *p,*q;
 	if(i<1||i>l->length) return ERROR;
	if((!(l->length))||((l->elem[i-1]%2)!=0)) return 0;
	p=&(l->elem[l->length-1]);
	q=&(l->elem[i-1]);
	*e=*q;
	for(++q;q<=p;q++)
	*(q-1)=*q;
	l->length--;
	return ok;
 }
 
 status fun2(elemtype m) 
 {
 	printf("%d ",m);
	return ok;
 }
 
 status	ListTraverse(sqlist l, status (*fun2) (elemtype m))
 {
	if(!(l.length)) return ERROR;
	elemtype *p=l.elem;
	int i=1;
	printf("遍历检验:") ;
	while(i<=l.length&&(*fun2)(*p++)) 	i++;
	printf("\n\n") ;
	return ok; 
 }

int main()
{
	sqlist l;
	int i,e,location,m,j=30;
	InitList(&l);//操作A 
	ListTraverse(l, fun2);
	printf("B测试: \n"); //操作B 
	for(i=1;i<=30;i++)
	{
		e=rand()%100+1;
		ListInsert(&l,i,e); 
	 } 
	ListTraverse(l, fun2);
	 
	 
	printf("C测试: \n");	//操作C
	location=LocateElem(l,5,fun1);
	printf("第一个个位5的位置:%d\n",location);
	ListTraverse(l, fun2);
	
	printf("D测试: \n");	//操作D
	printf("删除的偶数:"); 
	for(i=1;i<=j;i++)
	 {
	 	e=0;
	 	m=ListDelete(&l, i, &e);
	 	if(m)
	 	{
	 		i--;j--;
			printf("%d ",e);
		 }
	}
	printf("\n");
	ListTraverse(l, fun2);
	return 0;
 } 

1.2 链式表示

1.2.1 单链表

练习1 逆序插入
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
	int data;
	struct node *next; 
}Node,*linklist;

linklist create()
{
	printf("请输入测试数据:");
	linklist h,r,s;
	int x;
	h=(linklist)malloc(sizeof(Node));
	r=h;
	r->next=0;
	scanf("%d",&x);
	while(x!=-1)
	{
		s=(linklist)malloc(sizeof(Node));
		s->data=x;
		s->next=r->next;
		r->next=s;
		scanf("%d",&x);
	}
	
	return h; 
}
void funa(linklist head)
{
	printf("A:请输出链表结点值:"); 
	linklist p;
	p=head->next;
	while(p)
	{
		printf("%d ",p->data);
		p=p->next;
	}
	printf("\n"); 
}

void funb(linklist head)
{
	printf("B:请输出链表结点值:");
	linklist p,q,s;
	p=head->next;
	q=head;
	while(p)
	{
		if((p->data)%2==0)
		{
			s=(linklist)malloc(sizeof(Node));
			s->data=3*(p->data);
			s->next=q->next;
			q->next=s;
			printf("%d ",s->data);
		 } 
		
		 	q=p;
		 	p=p->next;
		 	printf("%d ",q->data);
	 } 
	 printf("\n");
}

void func(linklist head)
{
	printf("C:请输出链表结点值:");
	linklist p,q,s;
	p=head->next;
	q=head;	
	while(p)
	{
		if((p->data)%10==2)
		{
			s=p;
			p=p->next;
			q->next=p;
			free(s);
		}
		else
		{
			q=p;
			p=p->next;	
		}
		
	 }	
	 p=head->next;
	 while(p)
	{
	 printf("%d ",p->data); 
	 p=p->next;
	}
}
int main()
{
	linklist head;
	head=create();
	funa(head);
	funb(head);
	func(head);
	return 0;
 } 
 /*1 2 3 4 5 -1*/ 
练习2 求最值
#include<stdio.h>
#include<stdlib.h>
typedef struct node{
	int data;
	struct node *next;
	
}Node,*Linklist;


Linklist create()//创建链表 
{
	Linklist h,r,s;
	h=(Linklist)malloc(sizeof(Node));
	r=h;
	for(int m=1;m!=-1;m=s->data)//以-1作结束标志 
	{
		s=(Linklist)malloc(sizeof(Node));
		scanf("%d",&s->data);
		r->next=s;
		r=s;
	}
	r->next=0;
	return h;
 } 
 
void find(Linklist listhead,int *big,int *small)//求最值并输出 
{
	Linklist p;
	p=listhead->next;
	*big=p->data;
	*small=p->data;
	for(;p->next!=0;)
	{
		if(p->data>*big) *big=p->data;
		if(p->data<*small) *small=p->data;
		p=p->next;	
	 } 
	 
}

int main()//主函数 
{
	int max,min;
	printf("请输入测试数据:"); 
	Linklist head;
	head=create();
	find(head,&max,&min);	
	printf("请输出最值:min=%d max=%d\n",min,max) ;	
	return 0;
 } 
 /*测试样例 4 25 90 34 17 86 63 48 51 15 -1*/

1.2.2 静态链表

#include<stdio.h>
#define maxsize 100
typedef char elemtype; 
typedef struct{
	elemtype data;
	int cur;
}component,sqlinklist[maxsize];

void init_list(sqlinklist space)
{
	for(int i=0;i<maxsize-1;i++)
	{
		space[i].cur=i+1;
	}
	space[maxsize-1].cur=0;
}

int malloc_list(sqlinklist space)
{
	int i=space[0].cur;
	if(i!=0)
	space[0].cur=space[i].cur;
	return i;	
 } 

void free_list(sqlinklist space,int a)
{
	space[a].cur=space[0].cur;
	space[0].cur=a;
}

int create_list(sqlinklist space,int m)
{
	int s,r,i;
	s=malloc_list(space);
	r=s;
	for(int j=0;j<m;j++)
	{
		i=malloc_list(space);
		scanf("%c",&space[i].data);
		space[r].cur=i;
		r=i;
	}
	space[r].cur=0;
	return s;
}

void insert_list(sqlinklist space,int r,elemtype b)
{
	
	int i=malloc_list(space);
	space[i].data=b;
	space[i].cur=space[r].cur;
	space[r].cur=i;
}

void delete_list(sqlinklist space,int s,elemtype c)
{
	int p,q;
	q=s;
	while(q)
	{
		p=q;
		q=space[q].cur;
		if(space[q].data==c) break;	
	} 
	space[p].cur=space[q].cur;
	free_list(space,q);
}

int locate_list(sqlinklist space,int s,elemtype c)
{
	
	int q;
	q=s;
	while(q)
	{
		q=space[q].cur;
		if(space[q].data==c) break;	
	}
	if(q) return 1;
	else return 0;
}

void traverse_list(sqlinklist space,int s)
{
	
	int q=space[s].cur;
	while(q)
	{
		printf("%c",space[q].data);
		q=space[q].cur;
	}
}

int main()
{
	sqlinklist space;
	init_list(space);
	int m,n,s;
	char c;
	scanf("%d%d",&m,&n);
	getchar();
	s=create_list(space,m);

	getchar();
	int r=s;
	while(r)
	{
		r=space[r].cur;
		if(space[r].cur==0) break;
	}
	for(int j=0;j<n;j++)
	{
		scanf("%c",&c);
		if(locate_list(space,s,c)) delete_list(space,s,c);
		else insert_list(space,r,c);
	}
	traverse_list(space,s);
	return 0;
 } 

1.2.3 循环链表

将链表的最后一个结点与第一个结点连接起来,可从任意结点出发访问其它结点

1.2.4 双向链表

每个结点中有两个指针,一个指向其后继结点,另一个指向其前趋结点

2 习题

1.假设:有两个集合 A 和 B 分别用两个线性表 LA 和 LB 表示,设计算法,求一个新的集合A=A∪B

==*加代码==

2.已知线性表LA和LB中的数据元素按值非递减有序排列,现要求将LA和LB归并为一个新的线性表LC,且LC中的数据元素仍按值非递减有序排列。

==*加代码==

3 附录——ADT定义

ADT List {
数据对象:D={ai|ai∈ElemSet,i=1,2,...,n, n≥0 }
数据关系:R1={<ai-1 ,ai>|ai-1 ,ai∈D, i=2,...,n }
基本操作:
InitList(&L)
    操作结果:构造一个空的线性表L。
ListLength(L)
    初始条件:线性表L已存在。
    操作结果:返回L中元素个数。
GetElem(L, i, &e)
    初始条件:线性表L已存在, 1≤i≤ListLength(L)
    操作结果:用e返回L中第i个元素的值
LocateElem(L, e, compare( ))
    初始条件:线性表L已存在.
    操作结果:返回L中第1个与e满足关系compare( )的元素的位序,不存在则返回0。重要:ADT中compare()这种形式,语言级别对应为函数指针!
ListInsert(&L, i, e)
    初始条件:L已存在,1≤i≤ListLength(L)+1
    操作结果:在L的第i个位置插入新的元素e,L的长度增1
ListDelete(&L, i, &e)
    初始条件:L已存在且非空,1≤i≤ListLength(L)
    操作结果:删除L的第i个元素,并用e返回其值,L的长度减1
ListTraverse(L, visit( ))
    初始条件:线性表L已存在
    操作结果:依次对L的每个数据元素调用visit()函数,若visit()失败则操作失败
}ADT  List

文章作者: 猴猴猴
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 猴猴猴 !
  目录