数据结构 顺序表

一,数据

1.1数据的概念

        数据:被计算识别,存储,处理的符号。

        【整数,小数,字符串,汉字,声音,图片,视频,文件,app等】

        数据元素:由数据项组成,是数据的基本单位

        数据项:是数据的最小单位

        数据对象:由类型相同的数据元素组成

        数据>数据对象>数据元素>数据项

1.2数据结构

        数据结构:存储数据元素之间一种或多种关系的集合

        D_S=(D,R)

        1.2.1逻辑结构

                逻辑结构:表示一种或多种关系

                集合结构:数据元素之间没有关系【地铁上的人】

                线性结构:数据元素之间存在一对一的关系【地铁上的座位】

                                头结点无前驱,尾结点无后继,其他结点有唯一的前驱,唯一的后继

                树形结构:数据元素之间存在一对多的关系【族谱,公司架构】

                                     头结点无前驱,尾结点无后继,其他结点有唯一的前驱,多个后继                                 

                图形结构:数据元素之间存在多对多的关系【地图】

        1.2.2存储结构/物理结构

                存储结构:逻辑结构在计算机的一种存储形式

                顺序存储:使用一段连续的存储空间存储数据元素【数组】

                                        逻辑相邻,物理也相邻

                链式存储:使用任意一块空间存储数据元素

                                   逻辑相邻,物理不一定相邻

                散列存储:哈希存储,通过关键字映射在计算机的相应位置的一种查找算法【词典】

                索引存储:通过索引表和数据表实现的查找方式

1.3 时间复杂度

时间复杂度:表示代码的执行次数

T(n)=O(f(n))

T:time

T(n):时间复杂度

O:渐进符

n:问题规模

f(n):问题规模的函数

时间复杂度:只保留最高阶

f(n)=2*n^2+3*n^3+n+100

T(n)=O(n^3)

1.O(1):没有循环

2.O(n):一层循环

3.O(n^2):二层循环

4.O(log 2 n):对数阶

二,线性表

        线性表:用来存储类型相同的数据元素的有限集合【数组,星座】

        1>逻辑结构:线性结构【1对1】

        2>存储结构:顺序存储,链式存储

        线性表:顺序表,链表,栈,队列,字符串

三,顺序表

        1>顺序表:线性表的顺序存储称为顺序表

        2>顺序表是借助于一维数组实现的,但是顺序表不等价于一维数组

        3>顺序表下标从0开始

        4>线性表长度/数组长度:顺序表的最大空间,一旦申请空间,则不会改变

        # define MAXSIZE 8

        5>顺序表长度:实际数据元素的个数,会随着数据元素的增删会发生改变,int len

         len:临时充当下标,表示个数

3.2顺序表操作

        1.顺序表堆区空间创建

        2.顺序表表尾插入

        3.顺序表表尾删除

        4顺序表判满

        5.顺序表判空

        6.顺序表按下标插入

        7.顺序表按下标删除

        8.顺序表按下标修改

        9.顺序表按下标查找

       

        10.顺序表按元素插入

                在查找元素下标的后面插入

                参数:

        11.顺序表按元素删除

        12.顺序表按元素修改

        13.顺序表按元素查找

        14.顺序表排序

        17.顺序表空间释放

linux@linux:~/23041/day14$ cat main.c test.c
#include "head.h"
int main(int argc,const char *argv[])
{  
	seqlist *list=create();//创建一个顺序表即可
	menue();
	int number;
	while(1)
	{
		printf("请输入你的选择:\n");
		scanf("%d",&number);
		switch(number)
		{
		case 1:
			{
				int n,i;
				int e;
				puts("请输入尾插个数");
				scanf("%d",&n);
				for(i=0;i<n;i++)
				{
					puts("请输入您要插入的元素");
					scanf("%d",&e);
					insert_rear(e,list);
				}
				break;
			}
		case 2:
			{
				delete_rear(list);
				break;
			}
		case 3:
			   { 
				   output(list);
				   break;
			   }
    	case 4:
			   { 
				   puts("请输入你想查找的元素下标");
				   int sub;
				   scanf("%d",&sub);
				   serc_seqlist(list,sub);
				   break;
			   }
		case 5:
			   { 
				   puts("请输入你想修改的元素下标:");
				   int sub,change;
				   scanf("%d",&sub);
				   puts("请输入你想修改后的值:");
				   scanf("%d",&change);
				   change_seq(list,sub,change);
				   break;
			   }
		case 6:
			   { 
				   puts("请输入你想插入的元素下标:");
				   int sub,e;
				   scanf("%d",&sub);
				   puts("请输入你想插入后的值:");
				   scanf("%d",&e);
				   insert_row(list,sub,e);
				   break;
			   }
		case 7:
			   { 
				   puts("请输入你想删除的元素下标:");
				   int sub;
				   scanf("%d",&sub);
				   delete_row(list,sub);
				   break;
			   }
		case 8:
			   { 
				   puts("请输入你想查找的元素:");
				   int sub;
				   scanf("%d",&sub);
				   sele_seqlist(list,sub);
				   break;
			   }
    	case 9:
			   { 
				   puts("请输入你想修改的元素:");
				   int sub,e;
				   scanf("%d %d",&sub,&e);
				   change_ele(list,sub,e);
				   break;
			   }
     	case 10:
			   { 
				   puts("请输入你想插入的元素:");
				   int sub,e;
				   scanf("%d %d",&sub,&e);
				   insert_ele(list,sub,e);
				   break;
			   }	
		case 11:
			   { 
				   puts("请输入你想删除的元素:");
				   int sub;
				   scanf("%d ",&sub);
				   delete_ele(list,sub);
				   break;
			   }
		case 12 :{
					 maopao(list);
					   break;
				 }
		case 13:
	             {
					 chose(list);
					 break;
				   }
		case 14:
				 {
					 list=free_space(list); 
					 break;
				 }
								 

				   
		default:printf("输入有误,请重新输入\n");break;
		case 0:printf("退出程序\n");exit(0);

		}

	}
	return 0;
}


#include "head.h"
void menue()
{
	puts("******************");
	puts("\t1.表尾部插入");
	puts("\t2.表尾删除");
	puts("\t3.顺序表按下表遍历");
	puts("\t4.顺序表按下标查找");
	puts("\t5.顺序表按下标修改");
	puts("\t6.顺序表按下标插入");
	puts("\t7.顺序表按下标删除");
	puts("\t8.顺序表按元素查找");
	puts("\t9.顺序表按元素修改");
	puts("\t10.顺序表按元素插入");
	puts("\t11.顺序表按元素删除");
	puts("\t12.顺序表冒泡排序");
	puts("\t13.顺序表选择排序");
	puts("\t0.exit");
	puts("******************");
}
seqlist *create()//创建顺序表
{
	seqlist *list=(seqlist *)malloc(sizeof(seqlist));
	if(list==NULL)
		return NULL;
	//申请成功后
	list->len=0;//对顺序表清空
	return list;
}
int insert_rear(int e,seqlist *list)//尾插
{
	if(list==NULL||fullsqlist(list))//判断顺序表是否满,插入失败条件
	{   puts("插入失败");
		return -1;
	}
	//可以插入
	list->data[list->len]=e;
	list->len++;
	return 0;
}
int  output(seqlist *list)//输出
{
	if(list==NULL||emptysqlist(list))
		return -1;
	int i;
	for(i=0;i<list->len;i++)
	{
		printf("%d\t",list ->data[i]);
	}
	puts("");
	return 0;
}
int fullsqlist(seqlist *list)//判断是否未满
{
	return list->len==MAXSIZE?-1:0;
}
int emptysqlist(seqlist *list)
{
	return list->len==0?-1:0;
}
int delete_rear(seqlist *list)//尾删
{
	if(list==NULL||emptysqlist(list))
	{
		printf("删除失败\n");
		return -1;
	}
	list->len--;
	puts("DELETE SUCCESS!");
	return 0;
}
int serc_seqlist(seqlist *list,int sub)//按下标查找
{
     if(list==NULL||emptysqlist(list)||sub<0||sub>=list->len)
	 {	puts("查找失败");
		 return -1;}
	 printf("你想要查找的元素是%d\n",list->data[sub]);
	 return 0;

}
int change_seq(seqlist *list,int sub,int change)//按下标修改
{
     if(list==NULL||emptysqlist(list)||sub<0||sub>=list->len)
	 {	puts("不能修改");
		 return -1;}
	 list->data[sub]=change;
	 printf("修改成功\n");
	 return 0;

}

int insert_row(seqlist *list, int sub,int e)//按下标插入
{
	if(list==NULL||fullsqlist(list)||sub<0||sub>list->len)
	{
		puts("插入失败");
		return -1;
	}
	int i;
	for(i=list->len;i>sub;i--)
		list->data[i]=list->data[i-1];
	list->data[sub]=e;
	list->len++;
	puts("插入成功");
	return 0;
}
int delete_row(seqlist *list, int sub)//按下标删除
{
	if(list==NULL||emptysqlist(list)||sub<0||sub>=list->len)
	{
		puts("删除失败");
		return -1;
	}
	int i;
	for(i=sub;i<list->len-1;i++)
		list->data[i]=list->data[i+1];
	list->len--;
	puts("删除成功");
	return 0;
}
int sele_seqlist(seqlist *list,int sub)//按元素查找
{
     if(list==NULL||emptysqlist(list))
	 {	
		 puts("查找失败");
		 return -1;
	 }
	 int count=0,i;
	 for(i=0;i<list->len;i++)
		 if(sub==list->data[i])
		 {
			 printf("你所要找到的元素下标为:%d\n",i);
			 count++;
		 }
	 if(count==0) 
		 return -1;
	 return 0;

}
int change_ele(seqlist *list,int sub,int change)//按元素修改
{
     if(sele_seqlist(list,sub))
	 {	puts("不能修改");
		 return -1;}
	 int i;
	 for(i=0;i<list->len;i++)
		 if(sub==list->data[i])
		 {
			 list->data[i]=change;
			 break;
		 }
	 printf("修改成功\n");
	 return 0;

}
int delete_ele(seqlist *list, int sub)//按元素删除
{
	if(sele_seqlist(list,sub))
	{
		puts("删除失败");
		return -1;
	}
	int i;
	 for(i=0;i<list->len;i++)
		 if(sub==list->data[i])
		 {
			 delete_row(list,i);
			 break;
		 }
	return 0;
}
int insert_ele(seqlist *list, int sub,int e)//按元素插入
{
	if(sele_seqlist(list,sub)||fullsqlist(list))
	{
		puts("插入失败");
		return -1;
	}
	int i;
     for(i=0;i<list->len;i++)
		 if(sub==list->data[i])
		 {
			 insert_row(list,i,e);
			 break;
		 }
	return 0;
}
int maopao(seqlist *list)
{
	if(list==NULL||emptysqlist(list))
	{
		puts("排序失败");
		return -1;
	}
	int temp,i,j,count;
	for(i=1;i<list->len;i++)
	{
		count=0;
		for(j=0;j<list->len-i;j++)
		{
			if(list->data[j]>list->data[j+1])
			{
				temp=list->data[j];
				list->data[j]=list->data[j+1];
				list->data[j+1]=temp;
				count++;
			}

		}
		if(count==0)
			return 0;
	}
	return 0;
}
int chose(seqlist *list)
{
	if(list==NULL||emptysqlist(list))
	{
		puts("排序失败");
		return -1;
	}
	int temp,i,j,max;
	for(i=1;i<list->len;i++)
	{
		max=list->len-i;
		for(j=0;j<list->len-i;j++)
		{
			if(list->data[j]>list->data[max])
			{
				max=j;
			}

		}
            	temp=list->data[list->len-i];
				list->data[list->len-i]=list->data[max];
				list->data[max]=temp;


		}
	return 0;
}
seqlist *free_space(seqlist *list)
{
	if(list==NULL)
		return NULL;
	free(list);
	list=NULL;
	return list;
}


18顺序表优缺点

1>顺序表插入和删除时间的复杂度是O(n),修改和查找时间复杂度O(1)

2>顺序表方便修改和查找,不方便插入和删除【插入和删除需要大量元素】

3>顺序表逻辑相邻,物理相邻

4>顺序表需要提前预估存储空间MAXSIZE

5>顺序表一般用来存储数据量较小的情况

6>顺序表的存储密度为1

7>顺序表属于静态分配空间

一,链表

1>链表:线性表的链式存储称为链表

2>逻辑结构:线性结构【一对一】

3>存储结构:链式存储  【逻辑相邻,物理不一定相邻】

4>链表类型:单向链表,单向循环链表,双向链表,双向循环链表

5>结点:存储数据元素和数据元素之间关系的构造类型

               单向链表的结点:一个数据域,一个指针域

               双向链表的结点:一个数据域,两个指针域

6>头结点和头指针

7>结点的结构体构成

typedef struct Node//结构体名node不可以省略

{

        //数据域

union 

{

        int len;//头结点的数据域

        int data;//其他结点的数据域

};

        typedef struct 

{

       char name[10];

        int age;

        float score;  

}student;

        struct Node *next  头指针

}*linkist;

1.1单项链表的操作

1.单向链表结点的创建

2.单向链表结点的头插

永远表示在头节点的后面插入

3.单向链表结点的尾插

4.单向链表结点的遍历

5.单向链表结点的头删

6.单向链表结点的尾删

7.单向链表结点按位置插入

8.单向链表结点的按位置删除

9.单向链表结点的按位置修改

10.单向链表结点的按位置修改

#include "head.h"
int main(int argc,const char *argv[])
{  
	menue();
	int number;
	linklist L=create(1);
	while(1)
	{
		printf("请输入你的选择:\n");
		scanf("%d",&number);
		switch(number)
		{
		case 1:
			{
				datatype e;
				int n,i;
				puts("请输入元素的个数");
				scanf("%d",&n);
				for(i=0;i<n;i++)
				{
					printf("您输入的是第%d个元素\n",i);
					scanf("%d",&e);
					insert_head(L,e);
				}
			}
			break;
		case 2:
			output(L);
			break;
		case 3:
			{
				datatype e;
				int n,i;
				puts("请输入元素的个数");
				scanf("%d",&n);
				for(i=0;i<n;i++)
				{
					printf("您输入的是第%d个元素\n",i);
					scanf("%d",&e);
					insert_rear(L,e);
				}
			}

			break;
		case 4:
			delete_head(L);
			break;
		case 5:
			delete_rear(L);
			break;
		case 6:
			{
				int pos;
				datatype e;
				puts("请输入位置和元素");
				scanf("%d %d",&pos,&e);
				insert_pos(L,pos,e);

			}

			break;
		case 7:
			{
				int pos;
		    	puts("请输入位置");
				scanf("%d",&pos);
				find(L,pos);


			}
			break;
		case 8:
              {	
				  int pos;
		    	puts("请输入删除位置");
				scanf("%d",&pos);
				delete_pos(L,pos);
			  }

			break;
		case 9:	
			{
				datatype key,e;
				printf("请输入查找的值和修改的元素\n");
				scanf("%d %d",&key,&e);
				change_data(L,key,e);
			}

			break;
		case 10:
			{
				datatype key,e;
				printf("请输入删除的元素\n");
				scanf("%d",&key);
				delete_data(L,key);

			}
			break;
		case 11:
			{
				datatype key,e;
				printf("请输入查找的值和插入的元素");
				scanf("%d %d",&key,&e);
				insert_data(L,key,e);
			}
			break;
		case 12:
			{
				int pos;	
				datatype e;
				printf("请输入查找的位置和修改的元素\n");
				scanf("%d %d",&pos,&e);
				change_data(L,pos,e);
			}

			break;
		case 13:
			break;
		case 14:
			{
				datatype key;
				printf("请输入查找的值\n");
				scanf("%d",&key);
				int flag=find_data(L,key);
				if(flag==-1)
				{
					puts("can not find!");
				}else
					printf("是第%d个元素\n",flag);
			}
			break;
		case 15:
			linklist_rev(L);
			break;
		default:
			printf("您输入的命令有误\n");
			break;
		case 0:
			puts("EXIT SUCCESS!");
			exit(0);
			break;
		}
	}
	L=free_space(L);
	return 0;
}
#include "head.h"
void menue()
{
	puts("********************");
	puts("\t1.单项链表头插");
	puts("\t2.单项链表遍历");
	puts("\t3.单项链表尾插");
	puts("\t4.单项链表头删");
	puts("\t5.单项链表尾删");
	puts("\t6.单项链表按位置插入");
	puts("\t7.单项链表按位置查找");
	puts("\t8.单项链表按位置删除");
	puts("\t9.单项链表按元素修改");
	puts("\t10.单项链表按元素删除");
	puts("\t11.单项链表按元素插入");
	puts("\t12.单项链表按位置修改");
	puts("\t13.单项链表排序");
	puts("\t14.单项链表按元素查找");
	puts("\t15.逆置");
	puts("********************");
}
linklist create(int flag)
{
	//创建头结点
	linklist L=(linklist)malloc(sizeof(struct Node));
	if(L==NULL)
	{
		return NULL;
	}
	//成功
	//对头结点L的数据域初始化
	if(flag==1)
	L->len=0;
	else if(flag==0)
		L->data=0;
	//对头结点的指针域初始化
	L->next=NULL;
	return L;
}
int insert_head(linklist L,datatype e)
{
	if(L==NULL)//判断链表是否创建
	{
		puts("插入失败");
		return -1;
	}
	//头插:创建一个新结点s
	linklist s=create(0);
	if(s==NULL)
		return -1;
	//新节点s创建成功 数据域赋值
	s->data=e;
	//指针域赋值
	s->next=L->next;
	L->next=s;
	L->len++;
	return 0;
}
void  output(linklist L)
{
	if(L==NULL||L->next==NULL)
		printf("没有输出\n");
	linklist p=L;
	/*int i;
	for(i=0;i<L->len;i++)
	{
		p=p->next;
		printf("%d\t",p->data);
	}*/
	while(p->next!=NULL)
	{
    	p=p->next;
		printf("%d\t",p->data);
	}
	puts("");


}
int insert_rear(linklist L,datatype e)
{
	if(L==NULL)//判断链表是否创建
	{
		puts("插入失败");
		return -1;
	}
	//尾插:遍历
	linklist p=L;
	while(p->next!=NULL)
	{
    	p=p->next;
	}
	linklist s=create(0);//创建一个新结点
	if(s==NULL)
		return -1;
	s->data=e;
	p->next=s;
	L->len++;
	puts("插入成功");
	return 0;
}
int delete_head(linklist L)
{
	if(L==NULL||L->len==0)
	{	puts("删除失败");
		return -1;}
	linklist q=L->next;
	L->next=L->next->next;
	L->len--;
	free(q);
	q=NULL;
	puts("删除成功");
	return 0;
}
int delete_rear(linklist L)
{
	if(L==NULL||L->len==0)
	{	puts("删除失败");
		return -1;}
	linklist p=L;
	while(p->next->next!=NULL)
	{
		p=p->next;
	}
	 free(p->next);
     p->next=NULL;
	 L->len--;
	puts("删除成功");
	return 0;
}
int  insert_pos(linklist L,int pos,datatype e)
{
	if(L==NULL||pos<1||pos>L->len+1)
	{
		puts("成功插入");
		return -1;
	}
	linklist p=L;
	int i;
	for(i=0;i<pos-1;i++)
		p=p->next;
	linklist s=create(0);
	if(s==NULL)
		return -1;
	s->data=e;
	s->next=p->next;
	p->next=s;
	L->len++;
	puts("成功插入");
	return 0;

}
int find(linklist L,int pos)
{
	if(L==NULL||L->next==NULL)
	{
		puts("Can not find!Try again!");
		return -1;
	}
	linklist p=L;
	int i;
	for(i=0;i<=pos;i++)
		p=p->next;
	printf("你想要查找的数据元素为:%d\n",p->data);
	return 0;
}
int delete_pos(linklist L,int pos)//按位置删
{
	if(L==NULL||L->next==NULL||pos<1||pos>L->len)
	{
		puts("delete failed! try again!");
		return -1;
	}
	linklist p=L;
	int i;
	for(i=0;i<pos-1;i++)
		p=p->next;
	linklist q=p->next;
	p->next=q->next;
	free(q);
	q=NULL;
	puts("delete successfully!");
	return 0;
}
int find_data(linklist L,datatype key)//按元素查找
{
	if(L==NULL||L->len==0)
		return -1;
	int count=0;
	linklist p=L;
	while(p->next!=NULL)
	{
		p=p->next;
		count++;
		if(p->data==key)
		{
			return count;

		}
	}
	return -1;
}
int insert_data(linklist L,datatype key,datatype e)
{
	int pos=find_data(L,key);
	if(pos==-1)
		return -1;
	insert_pos(L,pos,e);
	return 0;
}
int  linklist_rev(linklist L)
{
	if(L==NULL||L->next==NULL)
		return -1;
	linklist p=L->next;
	L->next=NULL;
	while(p!=NULL)
	{
		linklist t=p;
		p=p->next;
		//把t节点头插到
		t->next=L->next;
		L->next=t;
	}
	return 0;
}
linklist free_space(linklist L)
{
	if(L==NULL)
		return NULL;
	int n=L->len;
	int i;
	for(i=0;i<n;i++)
	{
		delete_head(L);
	}
	free(L);
	L=NULL;
	return L;
}
int change_pos(linklist L,int pos ,datatype e)//按位置修改
{
	if(L==NULL||L->len==0||pos<0||pos>L->len)
	{	
		puts("change failed!");
		return -1;
	}
	int i;
	linklist p=L;
	for(i=0;i<pos;i++)
	{
		p=p->next;
	}
	p->data=e;
	puts("change success!");
	return 0;
}

int change_data(linklist L,datatype key,datatype e)//按元素修改
{
	if(L==NULL||L->len==0)
		return -1;
	int pos=find_data(L,key);
	change_pos(L,pos,e);
	return 0;
}
int delete_data(linklist L,datatype key)//按元素删除
{
	if(L==NULL||L->len==0)
		return -1;
	int pos=find_data(L,key);
	delete_pos(L,pos);
	return 0;
}

三,单向循环链表

单向循环链表:尾结点的指针域存储头结点的地址

3.1单向循环链表的操作

#include "head.h"
int main(int argc,const char *argv[])
{
	loop_linklist L=create(1);
	int n,i;
	printf("input n:\n");
	scanf("%d",&n);
/*	datatype e;
	for(i=0;i<n;i++)
	{
		printf("the number is %d\n",i+1);
		scanf("%s",e);
			insert_head(L,e);
			output(L);
	}*/
      datatype e;
	for(i=0;i<n;i++)
	{
		printf("the number is %d\n",i+1);
		scanf("%s",e);
			insert_rear(L,e);
		
	}
	output(L);
	int m;
	scanf("%d",&m);
	joseph(L,m);
	return 0;
}
#include "head.h"
loop_linklist create(int flag)
{
	loop_linklist L=(loop_linklist)malloc(sizeof(struct Node));
	if(L==NULL)
		return NULL;
	//成功返回地址
	if(flag==1)//创建头结点
	{
		L->len=0;
	L->next=L;
	}
	else if(flag==0)//创建普通节点
	{
	strcpy(L->data,"");
	L->next=NULL;
	}
	return L;
}
int insert_head(loop_linklist L,datatype e)
{
	if(L==NULL)
		return -1;
	loop_linklist s=create(0);
	if(s==NULL)
		return -1;
	strcpy(s->data,e);
	s->next=L->next;
	L->next=s;
	L->len++;
	return 0;
}
void output(loop_linklist L)
{
	if(L==NULL||L->next==L)
		puts("遍历失败");
	loop_linklist p=L;
	while(p->next!=L)
	{
		p=p->next;
		printf("%s\t",p->data);
	}
	puts("");
}
void insert_rear(loop_linklist L,datatype e)
{
	if(L==NULL)
		puts("插入失败");
	loop_linklist p=L;
	while(p->next!=L)
	{
		p=p->next;
	}
	loop_linklist s=create(0);
	s->next=p->next;
	p->next=s;
	strcpy(s->data,e);
	L->len++;
}
int delete_head(loop_linklist L)//头删 
{
	if(L==NULL||L->next==L)
		return -1;
	loop_linklist q=L->next;
	L->next=q->next;
	free(q);
	q=NULL;
	L->len--;
	puts("delete success!");
	return 0;
}
int delete_rear(loop_linklist L)//尾删
{
	if(L==NULL||L->next==L)
		return -1;
	loop_linklist p=L;
	loop_linklist q;
	while(p->next->next!=L)
	{
		p=p->next;
	}
	q=p->next;
	p->next=q->next;
	free(q);
	q=NULL;
	L->len--;
	puts("delete success!");
	return 0;


}
void joseph(loop_linklist L ,int m)
{
	int n=L->len;
	loop_linklist p=L;
	int i,j;
	for(i=0;i<n;i++)//循环的轮数
	{
		for(j=0;j<m-1;j++)//m-1:第m个删除,但需要找到前一个
		{
			p=p->next;//循环后移
			if(p==L)//如果p是头结点,则头不能删除,需要往后移动
			{
				p=p->next;
			}
		}
		loop_linklist q=p->next;
		if(q==L)
		{
			q=q->next;
			p=p->next;
		}
		p->next=q->next;
		printf("%s\t",q->data);
		free(q);
		q=NULL;
		L->len--;
	}
}

        四,双向链表

        每个数据结点都有两个指针,指向前趋和后继。

#ifndef __HEAD_H__
#define __HEAD_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char datatype;//data==char
typedef struct Node
{
	union
	{
		int len;//头结点的数据域:链表长度
		char data;//其他节点的数据域:数据元素
	};
	//指针域:下一个节点的地址
	struct Node *next;
	//指针域:上一个节点的地址
	struct Node *prev;
}*double_linklist;
double_linklist create(int flag);
int insert_head(double_linklist L ,datatype e);
void output(double_linklist L);

#endif
#include "head.h"
double_linklist create(int flag)
{
	double_linklist L=(double_linklist)malloc(sizeof(struct Node));
	if(L==NULL)
		return NULL;
	if(flag==1)
	L->len=0;
	else if(flag==0)
	{
		L->data=0;
	}
	L->next=NULL;
	L->prev=NULL;
	return L;
}
int insert_head(double_linklist L ,datatype e)
{
	//1.判断是否创建成功
	if(L==NULL)
	{
		return -1;
	}
	double_linklist s=create(0);
	if(s==NULL)
		return -1;
	s->data=e;
	s->next=L->next;
	s->prev=L;
	L->next=s;
	if(L->next!=NULL)
	L->next->prev=s;
	L->len++;	
}
void output(double_linklist L)
{
	if(L==NULL||L->next==NULL)
		return;
	puts("->:");
		double_linklist p=L;
	while(p->next!=NULL)
	{
		p=p->next;
		printf("%c\t",p->data);
	}
	puts("");
	puts("<-:");
	while(p->prev!=NULL)
	{
		printf("%c\t",p->data);
		p=p->prev;
	}
	puts("");

}
void insert_rear(double_linklist L,datatype e)
{
	if(L==NULL)
		return;
	double_linklist p=L;
	while(p->next!=NULL)
	{
		p=p->next;
	}
	double_linklist s=create(0);
	if(s==NULL)
		return;
	s->data=e;
	s->next=p->next;
	s->prev=p;
	p->next=s;
	L->len++;
}
void delete_head(double_linklist L)
{
	if(L==NULL||L->next==NULL)
		return;
	linklist q=L->next;
	L->next=q->next;
	if(q->next!=NULL)
		q->next->prev=L;
	free(q);
	q=NULL;
	L->len--;

}
void delete_rear(double_linklist L)
{
	if(L==NULL||L->next==NULL)
	return;
	double_linklist p=L;
	while(p->next!=NULL)
		p=p->next;
	p->prev->next=NULL;
	free(p);
	p=NULL;
	L->len--;
}
void insert_pos(double_linklist L,int pos,datatype e)
{
	if(L==NULL||pos<1||pos>L->len+1)
		return;
	double_linklist p=L;
	double_linklist s=create(0);
	if(s==NULL)
		return;
	int i;
	for(i=0;i<pos-1;i++)
		p=p->next;
	s->data=e;
	s->next=p->next;
	s->prev=p;
	p->next=s;
	if(p->next!=NULL)
		p->next->prev=s;
	L->len++;

}
//按位置删除
void insert_pos(double_linklist L,int pos)
{
	if(L==NULL||pos<1||pos>L)
		return;
	double_linklist p=L;
	int i;
	for(i=0;i<pos-1;i++)
		p=p->next;
	double_linklist q=p->next;
	p->next=q->next;
	if(q->next!=NULL)
	{
		q->next->prev=p;
	}
	free(q);
	q=NULL;
	L->len--;

}
//按位置修改
void change_pos(double_linklist L,int pos,datatype e)
{
	if(L==NULL||pos<1||pos>L)
		return;
	double_linklist p=L;
	int i;
	for(i=0;i<pos;i++)
		p=p->next;
	p->data=e;
	puts("修改成功");
}
//按位置查找
void serh_pos(double_linklist L,int pos)
{
	if(L==NULL||pos<1||pos>L)
		return;
	double_linklist p=L;
	int i;
	for(i=0;i<pos;i++)
		p=p->next;
	printf("you found the   %c\n",p->data);
	
}




#include "head.h"
int main(int argc,const char *argv[])
{  
	double_linklist L=create(1);
	//循环头插
	int n;
	datatype e;
	puts("input inserting number");
	scanf("%d",&n);
	int i;
	for(i=0;i<n;i++)
	{
		printf("the number is%d\n",i);
		scanf(" %c",&e);
		//insert_head(L,e);
		insert_rear(L,e);
	}
	output(L);
	return 0;
}

五,双向循环链表

#ifndef __HEAD_H__
#define __HEAD_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef float datatype;//data==float
typedef struct Node
{
	union
	{
		int len;//头结点的数据域:链表长度
		datatype data;//其他节点的数据域:数据元素
	};
	//指针域:下一个节点的地址
	struct Node *next;
	//指针域:上一个节点的地址
	struct Node *prev;
}*loop_double_linklist;

#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,const char *argv[])
{  
	loop_double_linklist L=create(1);
	int n;
	datatype e;
	printf("请输入个数");
	scanf("%d",&n);
	for(i=0;i<n;i++)
	{
		printf("插入的值\n");
		scanf("%f",&e);
		insert_head(L,e);
	}
	return 0;
}
#include "head.h"
loop_double_linklist create(int flag)
{
	loop_double_linklist L=(loop_double_linklist)malloc(sizeof(struct Node));
	if(L==NULL)
		return NULL;
	if(flag==1)
	{
		L->len=0;
		L->next=L;
		L->prev=L;
	}else if(flag==0)
	{
		L->data=0;
		L->next=NULL;
		L->prev=NULL;
	}
	return L;
	
}
int insert_head(loop_double_linklist L,datatype e)//头插
{
	if(L==NULL)
		return -1;
	loop_double_linklist s=create(0);
	if(s==NULL)
		return -1;
	s->data=e;
	s->next=L->next;
	s->prev=L;
	L->next->prev=s;
	L->len++;
	return 0;
}
void output(loop_double_linklist L)//输出
{
	loop_double_linklist p=L;
	while(p->next!=L)
	{
		p=p->next;
		printf("%f\t",p->data);

	}
}
int insert_rear(loop_double_linklist L,datatype e)//尾插
{
	if(L==NULL)
		return -1;
	loop_double_linklist p=L->prev;
	loop_double_linklist s=create(0);
	if(s==NULL)
		return -1;
	s->data=e;
	s->next=L;
	S->prev=p;
	p->next=s;
	L->prev=s;
	return 0;
	
}
int delete_head(loop_double_linklist L)//头删
{
	if(L==NULL||L->next==L)
		return -1;
	loop_double_linklist p=L->next;
	L->next=p->next;
	p->next->prev=L;
	free(p);
	p=NULL;
	return 0;
}
int delete_rear(loop_double_linklist L)//尾删
{
	if(L==NULL||L->next==L)
		return -1;
	loop_double_linklist p=L->prev;
	L->prev=p->prev;
	p->prev->next=L;
	free(p);
	p=NULL;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值