Day03_数据结构(顺序结构单向链表单向循环链表双向链表双向循环链表)
01.顺序结构
main.c
#include "seq.h"
int main(){seq_p S=create_seqlist();inputall(S);insert_head(S);delete_head(S);insert_tail(S);delete_tail(S);insert_pos(S);delete_pos(S);update(S);int ret=findpos(S);printf("主函数输出查找后的列表%d\n",ret);seq_free(&S);output(S);return 0;
}
seq.c
#include "seq.h"
seq_p create_seqlist()
{seq_p S=(seq_p)malloc(sizeof(seq_list));if(S==NULL){return NULL;}bzero(S,sizeof(seq_list));return S;}
int empty_seq(seq_p S)
{if(S==NULL){printf("入参为空\n");return -2;}return S->len==0?1:0;
}
int full_seq(seq_p S)
{if(S==NULL){printf("入参为空\n");return -2;}return S->len==MAX?1:0;}
//输出数据函数
void output(seq_p S)
{if(S==NULL){return;}int n=empty_seq(S);if(n==1){printf("02:顺序列表为空,没有数据可以删除\n");return;}int i;for(i=0;i<S->len;++i){printf("%d ",S->arr[i]);}puts("");}
//输入数据函数
seq_p input(seq_p S)
{printf("请输入您需要插入的数据:");scanf("%d",&S->number);return S;
}
//先插入数据中的顺序列表
seq_p inputall(seq_p S)
{printf("请输入您要放入空列表中的个数:");scanf("%d",&S->num1);printf("请输入数据:");getchar();for(int i=0;i<S->num1;++i){scanf("%d",&S->arr[i]);S->len++;}return S;
}//头插
seq_p insert_head(seq_p S)
{ if(S==NULL){return NULL;}int m=full_seq(S);if(m==1){printf("01:顺序列表已满,不能插入数据\n");output(S);return S;}else if(m==0){input(S);int i;for(i=S->len-1;i>=0;--i){S->arr[i+1]=S->arr[i];}S->arr[0]=S->number;S->len++;printf("01:输出插入头部数据的顺序列表:\n");output(S);return S;}}
//头删
seq_p delete_head(seq_p S)
{if(S==NULL){return NULL;}int n=empty_seq(S);if(n==1){printf("02:顺序列表为空,没有数据可以删除\n");return S;}else if(n==0){for(int i=1;i<S->len;++i){S->arr[i-1]=S->arr[i];}S->len=S->len-1;printf("02:输出删除头部数据的顺序列表\n");output(S);return S;}}
//尾插
seq_p insert_tail(seq_p S)
{if(S==NULL){return NULL;}int m=full_seq(S); if(m==1){printf("03:顺序列表已满,不能插入尾部数据\n");output(S);return S;}else if(m==0){input(S);S->arr[S->len]=S->number;S->len++;printf("03:输出插入尾部数据的顺序列表\n");output(S);return S;}}
//尾删
seq_p delete_tail(seq_p S)
{if(S==NULL){return NULL;}int n=empty_seq(S);if(n==1){printf("04:顺序列表为空,尾部没有数据可以删除\n");return S;}else if(n==0){S->arr[S->len]=0;S->len=S->len-1;printf("04:输出删除尾部数据的顺序列表:\n");output(S);return S;}}
seq_p insert_pos(seq_p S)
{if(S==NULL){return NULL;}int m=full_seq(S);if(m==1){printf("05:顺序列表已满,不能插入按位置插入数据\n");output(S);return S;}else if(m==0){int number,pos;printf("05:请输入您需要插入的数据和位置:");scanf("%d%d",&number,&pos);if(pos<0||pos>S->len){printf("位置不合理.\n");return S;}int i;for(i=S->len-1;i>=pos;--i){S->arr[i+1]=S->arr[i];}S->arr[pos]=number;S->len++;printf("05:输出按位置插入数据的顺序列表:\n");output(S);return S;}
}
seq_p delete_pos(seq_p S)
{if(S==NULL){return NULL;}int n=empty_seq(S);if(n==1){printf("06:顺序列表为空,不能删除按位置插入数据\n");output(S);return S;}else if(n==0){int number,pos;printf("06:请输入您需要删除的数据和位置:");scanf("%d%d",&number,&pos);if(pos<0||pos>=S->len){printf("位置不合理\n");}int i;for(i=pos+1;i<=S->len;++i){S->arr[i-1]=S->arr[i];}S->len--;printf("06:输出按位置删除数据的顺序列表:\n");output(S);return S;}}//12.按位置修改元素
seq_p update(seq_p S)
{ if(S==NULL){return NULL;}int n=empty_seq(S);if(n==1){printf("12:顺序列表为空,不能按位置修改数据\n");output(S);return S;}else if(n==0){int number,pos;printf("12:请输入您需要修改的位置和数据:");scanf("%d%d",&number,&pos);if(pos<0||pos>=S->len){printf("位置不合理\n");}S->arr[pos-1]=number; printf("12:输出按位置修改数据的顺序列表:\n");output(S);return S;}}
//13.按值查找返回下标
int findpos(seq_p S)
{if(S==NULL){return -1;}int n=empty_seq(S);if(n==1){printf("13:顺序列表为空,不能按数据查找下标\n");output(S);return -1;}else if(n==0){int number,pos;printf("13:请输入您需要查找的数据");scanf("%d",&number);for(int i=0;i<S->len;++i){if(S->arr[i]==number){pos=i;printf("13_01:查找数据%d存在顺序列表中下标%d\n",number,pos); printf("13_02:输出查找后数据的顺序列表:\n");output(S);return pos;}} printf("13_03:查找数据%d不存在顺序列表中\n",number);return -2;printf("13_04:输出查找后数据的顺序列表:\n");output(S);}
}//释放顺序表
# if 0
void seq_free(seq_p S)
{printf("释放顺序列表前数据:\n");output(S);if(S!=NULL){free(S); }printf("%p\n",S);return;
}
#endif
#if 1
void seq_free(seq_p *S)
{printf("100:释放顺序列表前数据:\n");output(*S);//必须先判断S的值,再判断*S的值if(S==NULL||*S==NULL){printf("入参不合理\n");return;}free(*S);*S=NULL;printf("100:释放顺序列表后数据\n");printf("%p\n",S);return;
}
#endif
seq.h
#ifndef __SEQ_H__
#define __SEQ_H__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 6
typedef struct seq_list
{int arr[MAX];int len;int num1;//开始输入数组中个数int number;//输入数组中的数据int pos;//插入数组的位置
}seq_list,*seq_p;
seq_p create_seqlist();
int empty_seq(seq_p S);
int full_seq(seq_p S);
void output(seq_p S);
seq_p input(seq_p S);
seq_p inputall(seq_p S);seq_p insert_head(seq_p S);
seq_p delete_head(seq_p S);
seq_p insert_tail(seq_p S);
seq_p delete_tail(seq_p S);
void seq_free(seq_p *S);seq_p insert_pos(seq_p S);
seq_p delete_pos(seq_p S);
seq_p update(seq_p S);
int findpos(seq_p S);#endif
makefile
EXE=seq
Objs=$(patsubst %.c,%.o,$(wildcard *.c))
CC=gcc
CFlags=-c -o
all:$(EXE)
$(EXE):$(Objs)$(CC) $^ -o $@
%.o:%c$(CC) $^ $(CFlags) $@
.PHONY:clean
clean:rm -f $(Objs) $(EXE)
02.单向链表
main.c
#include "link.h"
int main()
{node_p H = create_link();insert_head(H,12);insert_head(H,34);insert_head(H,70);insert_head(H,6);show_link(H);printf("第2个位置的元素为%d\n",search_pos(H,2));update_value(H,12,100);show_link(H);reverse_link(H);printf("逆置后\n");show_link(H);return 0;
}
link.c
#include "link.h"
//1、申请单链表(头结点)
node_p create_link()
{node_p H = (node_p)malloc(sizeof(node));if(H==NULL){return NULL;}H->next = NULL;H->len = 0; //当只有头结点时,长度为0return H;
}
//2、申请数据结点
node_p create_node(int value)
{node_p new_node = (node_p)malloc(sizeof(node));if(new_node==NULL){printf("申请空间失败\n");return NULL;}new_node->data = value; //给数据结点的数据域赋值new_node->next = NULL; //数据节点的指针域赋值return new_node;
}
//3、判空
int empty_link(node_p H)
{if(H==NULL){return -1;}return H->next==NULL?1:0;
}
//4、头插
void insert_head(node_p H,int value)
{if(H==NULL){printf("入参为空,请检查\n");return;}//申请新结点node_p new = create_node(value);//让新结点指向原来头结点的后继结点new->next = H->next;//让头结点指向新结点H->next = new;//头结点保存的链表长度自增H->len++;
}
//5、尾插
void insert_tail(node_p H,int value)
{if(H==NULL){printf("入参为空,请检查\n");return;}//1、找到尾结点node_p p = H;//尾结点的条件p->next==NULL;while(p->next!=NULL){p = p->next; //找下一个结点}//2、申请新的数据结点node_p new = create_node(value);//3、让最后一个结点的指针域指向新结点p->next = new;//4、因为新结点的指针域在申请后已经置NULL了,无需再次重置H->len++;
}
//6、输出单向链表
void show_link(node_p H)
{if(H==NULL){return;}if(empty_link(H)){printf("链表为空,无需数超出\n");return;}//从第一个结点开始输出,//到最后一个结点结束,最后一个结点需要进入循环node_p p = H->next;while(p!=NULL){printf("%d->",p->data);p = p->next;}//退出循环说明p走到了NULL,遍历结束整条链表printf("NULL\n");
}
//7、头删
void delete_head(node_p H)
{if(H==NULL){return;}if(empty_link(H)){return;}//1、保存要删除结点的首地址node_p dele = H->next;//2、让头结点指向原来的第二个结点H->next = H->next->next; //H->next = dele->next;free(dele);H->len--;
}
//8、尾删
void delete_tail(node_p H)
{if(H==NULL){return;}if(empty_link(H)){return;}//由于是单向链表只能向后查找//所以需要找到倒数第二个结点node_p p = H;while(p->next->next!=NULL){p = p->next;}//退出循环说明找到倒数第二个结点node_p dele = p->next; //保存倒数第一个结点p->next = NULL; //给倒数第二个结点的指针域置空free(dele);H->len--;
}
//9、按位置插入
void insert_pos(node_p H,int pos,int value)
{if(H==NULL){return;}//第一个循环变量i记录位置if(pos<=0){printf("位置不合理\n");return;}int i = 0;//定义指针循环结点node_p p = H;for(i=0,p=H;i<pos-1;i++,p=p->next){//判断位置不合理的情况if(p==NULL){printf("插入位置不合理\n");return;}}node_p new = create_node(value);//新结点指向pos位置结点new->next = p->next;//pos-1位置结点,指向新结点p->next = new;H->len++;
}
//10、按位置删除
void dele_pos(node_p H,int pos)
{if(H==NULL){return;}if(pos<1){printf("位置不合理\n");return;}int i;node_p p;//删除pos位置还是找到pos-1位置结点for(i=0,p=H;i<pos-1;i++,p=p->next);//找到pos-1位置结点后,判断是否有pos位置的结点if(p->next==NULL){printf("位置不合理\n");return;}//保存要删除结点的首地址node_p dele = p->next;p->next = p->next->next; //p->next = dele->next;free(dele);H->len--;
}
//11、按位置查找返回元素的值
int search_pos(node_p H,int pos)
{if(H==NULL){return -2;}if(pos<1){return -1;}if(empty_link(H)){return -3;}int i;node_p p;for(i=1,p=H->next;i!=pos;i++,p=p->next){if(p==NULL){printf("位置不合理\n");return -1;}}return p->data;
}
//12、按值修改
void update_value(node_p H,int value,int new_value)
{if(H==NULL){return;}if(empty_link(H)){return;}node_p p = H->next;//循环整条链表for(;p!=NULL;p=p->next){if(p->data==value){p->data = new_value;return;}}
}
//13、逆置
void reverse_link(node_p H)
{if(H==NULL){return;}if(empty_link(H)){return;}if(H->next->next==NULL){return;}//提前将第二个结点开始链表保存下来node_p p = H->next->next;node_p q;//让原来的第一个结点变成现在的最后一个结点H->next->next = NULL;//循环头插//只要p的指向的结点不为空说明要头插while(p!=NULL){//先保留下一个要头插结点的首地址q = p->next;//头插p->next = H->next;H->next = p;p = q; //让p指向下一个要头插的结点}
}
link.h
#ifndef __LINK_H__
#define __LINK_H__
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{union{int data; //数据节点的数据域int len; //头结点的长度};struct node *next;
}node,*node_p;
//1、申请单链表(头结点)
node_p create_link();
//2、申请数据结点
node_p create_node(int value);
//3、判空
int empty_link(node_p H);
//4、头插
void insert_head(node_p H,int value);
//5、尾插
void insert_tail(node_p H,int value);
//6、输出单向链表
void show_link(node_p H);
//7、头删
void delete_head(node_p H);
//8、尾删
void delete_tail(node_p H);
//9、按位置插入
void insert_pos(node_p H,int pos,int value);
//10、按位置删除
void dele_pos(node_p H,int pos);
//11、按位置查找返回元素的值
int search_pos(node_p H,int pos);
//12、按值修改
void update_value(node_p H,int value,int new_value);
//13、逆置
void reverse_link(node_p H);#endif
03.单向循环链表
main.c
#include "loop.h"
int main()
{node_p H = create_loop();insert_head(H,67);insert_head(H,90);insert_head(H,34);insert_head(H,8);show_loop(H);printf("H->next=%p\n",H->next);H = delete(H); //删除头结点后链表已经没有头结点了//H需要重新被赋值show_no_head(H);return 0;
}
circle.c
#include "loop.h"
//1、申请单向循环链表
node_p create_loop()
{node_p H = (node_p)malloc(sizeof(node));if(H==NULL){printf("申请空间失败\n");return NULL;}H->len=0;H->next = H;return H;
}
//2、申请结点
node_p create_node(int value)
{node_p new = (node_p)malloc(sizeof(node));new->next = NULL;new->data = value;return new;
}
//3、判空
int empty_loop(node_p H)
{if(H==NULL){return -1;}return H->next==H?1:0;
}
//4、头插
void insert_head(node_p H,int value)
{if(H==NULL){return;}node_p new = create_node(value);//新结点的后继指向头结点的后继new->next = H->next;H->next = new;H->len++;
}
//5、尾插
void insert_tail(node_p H,int value)
{if(H==NULL){return;}node_p p=H; //p用于遍历链表,找到最后一个结点while(p->next!=H){p=p->next;}node_p new = create_node(value);//退出循环后p指向最后一个结点p->next = new;new->next=H;//new->next = p->next;//p->next = new;H->len++;
}
//6、头删
void dele_head(node_p H)
{if(H==NULL){return;}if(empty_loop(H)){return;}//保存要删除结点的首地址node_p p=H->next;//让头结点指向原来的第二个结点H->next=p->next;free(p);H->len--;return;
}
//7、尾删
void dele_tail(node_p H)
{if(H==NULL){return;}if(empty_loop(H)) {return;}node_p p=H;//尾删要找倒数第二个结点while(p->next->next!=H){p=p->next;}//循环退出时p指向倒数第二个节点node_p q=p->next;p->next=H;free(q);//free(p->next); //先释放最后一个结点//p->next = H;H->len--;
}
//8、输出
void show_loop(node_p H)
{if(H==NULL){return;}if(empty_loop(H)){return;}node_p p = H->next;while(p!=H){printf("%d->",p->data);p = p->next;}printf("H\n");
}
//9、删除单向循环链表的头结点
//删除头结点后需要返回给主调函数处新的链表的头
node_p delete(node_p H)
{if(H==NULL){return NULL;}if(empty_loop(H)){return NULL;}//保存第一个结点的首地址node_p p = H->next;//找到最后一个结点node_p tail = H->next;while(tail->next!=H){tail=tail->next;}//让最后一个结点的后继节点变成原来的第一个结点tail->next = p;//释放头结点free(H);return p;
}
//10、删除头结点后的单向循环链表的输出
void show_no_head(node_p H)
{if(H==NULL){return;}//不需要再判空//因为没有头结点了传过来的结点只要不是空说明链表中就有元素node_p p = H;do{printf("%d->",p->data);p = p->next;}while(p!=H);printf("H\n");//需要第一次循环时不判断条件//只能使用do··while
}
circle.h
#ifndef __LOOP_H__
#define __LOOP_H__
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{union{int len;int data;};struct node *next;
}node,*node_p;
//1、申请单向循环链表
node_p create_loop();
//2、申请结点
node_p create_node(int value);
//3、判空
int empty_loop(node_p H);
//4、头插
void insert_head(node_p H,int value);
//5、尾插
void insert_tail(node_p H,int value);
//6、头删
void dele_head(node_p H);
//7、尾删
void dele_tail(node_p H);
//8、输出
void show_loop(node_p H);
node_p delete(node_p H);
//10、删除头结点后的单向循环链表的输出
void show_no_head(node_p H);#endif
03.双向链表
main.c
#include "double.h"
int main()
{node_p H = create_double();insert_head(H,12);insert_head(H,34);insert_head(H,90);show(H);insert_pos(H,3,24);show(H);dele_pos(H,0);show(H);des_double(&H);printf("释放后\n");show(H);printf("H=%p\n",H);return 0;
}
double.c
#include "double.h"
//1、创建双向链表
node_p create_double()
{node_p H=(node_p)malloc(sizeof(node));if(H==NULL){return NULL;}H->len=0;H->next=NULL;H->pri=NULL;return H;
}
//2、创建结点
node_p create_node(int data)
{node_p new = (node_p)malloc(sizeof(node));if(new==NULL){return NULL;}new->data = data;new->pri = NULL;new->next = NULL;return new;
}
//3、判空
int empty_double(node_p H)
{if(H==NULL){return -1;}return H->next==NULL;
}
//4、头插
void insert_head(node_p H,int value)
{if(H==NULL){return;}node_p new = create_node(value);//新结点的后继保存原来头结点的后继new->next = H->next;//新结点的前驱指向头结点new->pri = H;//头结点后继节点的前驱指向新结点if(H->next!=NULL){H->next->pri = new;}//头结点的后继指向新结点H->next = new;H->len++;
}
//5、尾插
void insert_tail(node_p H,int value)
{if(H==NULL){return;}node_p p = H;while(p->next!=NULL){p = p->next;}node_p new = create_node(value);//新结点的前驱指向尾结点new->pri = p;//尾结点的后继指向新结点p->next = new;H->len++;
}
//6、输出
void show(node_p H)
{if(H==NULL){return;}if(empty_double(H)){return;}node_p p = H->next;while(p){printf("%d->",p->data);p = p->next;}printf("NULL\n");
}
//7、任意位置插入
void insert_pos(node_p H,int pos,int value)
{if(H==NULL){return;}if(pos<=0){return;}//找到pos-1位置的结点int i;node_p p;for(i=0,p=H;i<pos-1;i++,p=p->next){if(p==NULL){printf("位置不合理\n");return;}}//退出循环时p指向pos-1位置的结点if(p==NULL){printf("位置不合理\n");return;}node_p new = create_node(value);new->next = p->next;new->pri = p;if(p->next!=NULL){p->next->pri = new;}p->next = new;H->len++;
}
//8、头删
void dele_head(node_p H)
{if(H==NULL){return;}if(empty_double(H)){return;}//保存要删除结点的首地址node_p del = H->next;//如果链表中节点个数多于一if(del->next!=NULL){del->next->pri = H;}//让头结点的后继保存第一个结点的后继H->next = del->next;free(del);H->len--;
}
//9、尾删
void dele_tail(node_p H)
{if(H==NULL){return;}if(empty_double(H)){return;}//找到最后一个结点node_p p = H;while(p->next!=NULL){p = p->next;}//退出循环时p是最后一个结点//让倒数第二个结点的后继指向NULLp->pri->next = NULL;free(p);H->len--;
}
//10、按位置删除
void dele_pos(node_p H,int pos)
{if(H==NULL){return;}if(empty_double(H)){return;}if(pos<=0){return;}//找到pos位置的结点int i;node_p p;for(i=0,p=H;i<pos;i++,p=p->next){if(p==NULL){printf("位置不合理\n");return;}}//循环结束p指向pos位置的结点if(p==NULL){printf("位置不合理\n");return;}//pos+1结点的前驱指向pos-1结点 if(p->next!=NULL){p->next->pri = p->pri;}//pos-1结点的后继指向pos+1结点 p->pri->next = p->next;free(p);H->len--;
}
//11、按值查找返回位置
int search_value(node_p H,int value)
{if(H==NULL){return -1;}if(empty_double(H)){return -2;}
}
//12、按位置修改元素
void update_pos(node_p H,int pos,int new_value)
{if(H==NULL){return;}if(empty_double(H)){return;}if(pos<=0){return;}
}
//13、释放双向循环链表
void des_double(node_p *H)
{if(H==NULL||*H==NULL){return;}while((*H)->next){dele_head(*H);}//退出循环说明链表中只有头结点了free(*H);*H=NULL;
}
double.h
#ifndef __DOUBLE_H__
#define __DOUBLE_H__
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{union{int len;int data; };struct node *pri; //指向前驱结点的指针struct node *next; //指向后继结点的指针
}node,*node_p;
//1、创建双向链表
node_p create_double();
//2、创建结点
node_p create_node(int data);
//3、判空
int empty_double(node_p H);
//4、头插
void insert_head(node_p H,int value);
//5、尾插
void insert_tail(node_p H,int value);
//6、输出
void show(node_p H);
//7、任意位置插入
void insert_pos(node_p H,int pos,int value);
//8、头删
void dele_head(node_p H);
//9、尾删
void dele_tail(node_p H);
//10、按位置删除
void dele_pos(node_p H,int pos);
//13、释放双向循环链表
void des_double(node_p *H);#endif
04.双向循环链表
main.c
#include "dloop.h"
int main()
{node_p H=(node_p)create_dloop();//1.头插printf("请输出头插的第一个数字双向链表:\n");insert_head(H,4);show(H);printf("请输出头插的第二个数字双向链表:\n");insert_head(H,3);show(H);printf("请输出头插的第三个数字双向链表:\n");insert_head(H,2);show(H);printf("请输出头插的第四个数字双向链表:\n");insert_head(H,1);show(H);//2.尾插printf("请输出尾插的第一个数字双向链表:\n");insert_tail(H,5);show(H);printf("请输出尾插的第二个数字双向链表:\n");insert_tail(H,6);show(H);//3.按位置插入printf("请输出按位置插入双向链表:\n");insert_pos(H,3,77);show(H);//4.头删printf("请输出头删双向链表:\n");dele_head(H);show(H);//5.尾删printf("请输出头删双向链表:\n");dele_tail(H);show(H);//6.按位置删除printf("请输出按位置删除双向链表:\n");delete_pos(H,3);show(H);//7.按位置查找返回值int ret=search_value(H,2);printf("请输出按位查找的返回值%d:\n",ret);show(H);printf("销毁前:\n");printf("%p\n",H);free_loop(&H);printf("销毁后:\n");printf("%p\n",H);}
dloop.c
#include "dloop.h"
//1.创建双链表的空结点
node_p create_dloop()
{node_p H=(node_p)malloc(sizeof(node));if(H==NULL){printf("申请内存失败.\n");return NULL;}H->pri=H;H->next=H;H->len=0;return H;
}
//2.申请结点
node_p create_node(int value)
{node_p new=(node_p)malloc(sizeof(node));new->next=NULL;new->data=value;
}
//3.判空
int empty_dloop(node_p H)
{if(H==NULL){printf("入参为空.\n");return -1;}return H->next==H?1:0;
}
//4.头插
void insert_head(node_p H,int value)
{if(H==NULL){printf("入参为空.\n");return;}node_p new=create_node(value);new->next=H->next;new->pri=H;if(H->next!=NULL){H->next->pri=new;}H->next=new;H->len++;
}
//5.尾插
void insert_tail(node_p H,int value)
{if(H==NULL){printf("入参为空.\n");return;}int i;node_p new=create_node(value);node_p p=H;//1.找到了最后一个结点的位置while(p->next!=H){p=p->next;}new->pri=p;new->next=H;p->next=new;H->pri=new;H->len++;
}
//6.按位置插入
void insert_pos(node_p H,int pos,int value)
{if(H==NULL){printf("入参为空.\n");return;}if(pos<0){printf("插入位置的数据不合理.\n");return;}int i;node_p p;for(i=1,p=H->next;i<pos-1;i++,p=p->next){if(p==H){printf("位置不合理.\n");return;}}if(p==H){printf("位置不合理.\n");return;}node_p new=(node_p)create_node(value);new->next=p->next;new->pri=p;if(p->next!=H){p->next->pri=new;}p->next=new;H->len++;
}
//7.输出
void show(node_p H)
{if(H==NULL){printf("入参为空.\n");return;}if(empty_dloop(H)){printf("双向循环链表为空,无输出.\n");return;}node_p p=H->next;while(p!=H){printf("%d->",p->data);p=p->next;}printf("NULL\n");
}
//8.头删
void dele_head(node_p H)
{if(H==NULL){printf("入参为空.\n");return;}if(empty_dloop(H)){printf("循环双链表为空,无数据可删除.\n");return;}node_p dele=H->next;//判断是否就一个数据if(dele->next!=H){dele->next->pri=H;}H->next=dele->next;free(dele);H->len--;
}
//9.尾删
void dele_tail(node_p H)
{if(H==NULL){printf("入参为空.\n");return;}node_p p=H;while(p->next!=H){p=p->next;}p->pri->next=H;H->pri=p->pri;free(p);H->len--;
}
//10.按位置删除
void delete_pos(node_p H,int pos)
{if(H==NULL){printf("入参为空.\n");return;}if(empty_dloop(H)){printf("双向链表为空.\n");return;}node_p p;int i;for(i=1,p=H->next;i<pos;i++,p=p->next){if(p==H){printf("位置不合理.\n");return;}}if(p==H){printf("位置不合理.\n");return;}//1.pos+1结点的前驱指向pos-1结点if(p->next!=H){p->next->pri=p->pri;}//2.pos-1结点的后继指向pos+1结点p->pri->next=p->next;free(p);H->len--;
}//11.按位置查找返回值
int search_value(node_p H,int pos)
{if(H==NULL){printf("入参为空.\n");return -1;}if(empty_dloop(H)){printf("双向循环链表为空.\n");return -2;}int i;node_p p;for(i=1,p=H->next;i<pos;i++,p=p->next){if(p==H){printf("位置不合理.\n");return -3;}}if(p==H){printf("位置不合理.\n");return -3;}return p->data;
}
//12.释放链表
void free_loop(node_p *H)
{if(H==NULL||*H==NULL){printf("入参为空.\n");return;}while((*H)->next!=(*H)){dele_head(*H);}free(*H);*H==NULL;
}
dloop.h
#ifndef __DLOOP_H__
#define __DLOOP_H__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node
{union{int len;int data;};struct node *pri;struct node *next;
}node,*node_p;node_p create_dloop();
node_p create_node(int value);
int empty_dloop(node_p H);
void insert_head(node_p H,int value);
void insert_tail(node_p H,int value);
void insert_pos(node_p H,int pos,int value);
void show(node_p H);
void dele_head(node_p H);
void dele_tail(node_p H);
void delete_pos(node_p H,int pos);
int search_value(node_p H,int pos);
void free_loop(node_p *H);#endif