一,数据
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;
}