双向循环链表-C语言版

源文件部分:
#include<stdio.h>
#include<string.h>
#include<malloc.h>
typedef int Elemtype;
#include"Delist.h"
int main()
{
	Dlnode head=NULL;
	instruction(head);
	return 0;
}
头文件部分:
typedef struct DLnode
{
	Elemtype data;
	struct DLnode *prior;    //节点的声明定义
	struct DLnode *next;
}DLnode,*Dlnode;

void Init_Dlist(Dlnode &head)    //循环双向初始化
{
	head=(Dlnode)malloc(sizeof(DLnode));
	head->prior=head;
	head->next=head;
}

int Empty_Dlist(Dlnode head)       //双向判空
{
	if(head->prior==head&&head->next==head)
		return 1;
	return 0;
}

void Insert_Dlist(DLnode *head,Elemtype e)   //头插法-双向(新增)
{
	Dlnode p=NULL;
	p=(DLnode *)malloc(sizeof(DLnode));            //因为是双向循环链表,所以不存在双向的那个问题
	if(!p)
	{
		printf("对不起,已无更多的内存单元得到分配!!!\n");
		return ;
	}
	p->data=e;
	p->next=head->next;
	p->next->prior=p;
	p->prior=head;
//	printf("*%d*\n",head->next);
	head->next=p;
}

int Length_Dlist(Dlnode head)
{
	DLnode *p=NULL;
	int len=0;
	if(Empty_Dlist(head))
		return 0;
	p=head->next;
	while(p!=head)
	{
		len++;
		p=p->next;
	}
	return len;
}

int Delete_Dlist(DLnode *head,Elemtype where)        //按位置删除
{
	DLnode *p=NULL;
	int i=1;
	p=head->next;
	if(Empty_Dlist(head))
	{
		printf("对不起,链表是空的,无法完成删除操作!!!\n");
		return 0;
	}
	if(where>Length_Dlist(head)||where<0)
	{
		printf("对不起,你删除的位置是不合法的,请重新输入!!!\n");
		return 0;
	}
	while(i<where)
	{
		p=p->next;
		i++;
	}
	p->prior->next=p->prior->next->next;
	p->prior->next->prior=p->prior;
	printf("删除成功!!!\n");
	return p->data;
}

void Insearch_Dlist(Dlnode head,Elemtype e)      //按元素查找
{
	DLnode *p=NULL;
	int len=1;
	if(Empty_Dlist(head))
	{
		printf("对不起,链表是空的,无法完成查找操作!!!\n");
		return ;
	}
	p=head->next;
	while(p!=head)
	{
		if(p->data==e)
		{
			printf("你要查找的元素位于链表的第%d个位置上.\n",len);
			return ;
		}
		p=p->next;
		len++;
	}
	printf("对不起,你要查找的元素不存在,请重新输入!!!\n");
	return ;
}

void Modify_Dlist(DLnode *head,Elemtype where,Elemtype e)    //按位置修改
{
	DLnode *p=NULL;
	int len=1;
	p=head->next;
	while(len<where)
	{
		p=p->next;
		len++;
	}
	p->data=e;
	printf("修改成功!\n");
	return ;
}

void Print_Dlist(Dlnode head)          //打印操作
{
	Dlnode p=head->next;
	if(Empty_Dlist(head))
	{
		printf("对不起,链表是空的,无法完成打印操作!!!\n");
		return ;
	}
	while(head!=p)
	{
		printf("%d ",p->data);
		p=p->next;
	}
	printf("\n");
	return ;
}

void Destory_Dlist(Dlnode head)            //销毁清空操作
{
	Dlnode p=head->next;
	while(p!=head)
	{
		p->prior->next=p->next;
		p->next->prior=p->prior;
		p=head->next;
	}
	printf("销毁成功!\n");
}

void instruction(Dlnode head)             //功能函数
{
	int n,m,t,a,b,len1,index;
	printf("\t\t1、初始操作\n");
	printf("\t\t2、新增操作\n");              //为什么不能在这里定义head指针---因为每次调用功能函数后,head指针又被重新初始化了
	printf("\t\t3、删除操作\n");
	printf("\t\t4、查找操作\n");
	printf("\t\t5、修改操作\n");
	printf("\t\t6、销毁操作\n");
	printf("\t\t7、求长操作\n");
	printf("\t\t8、打印操作\n");
	printf("\t\t9、退出程序\n");
	printf("请输入你所需要完成的指令:\n");
	do{
		scanf("%d",&n);
		if(n<1||n>9)
			printf("对不起,你输入的指令编号是无效的,请重新输入!!!\n");
	}while(n<1||n>9);
	switch(n)
	{
		case 1:
			Init_Dlist(head);            //初始化操作
			printf("已完成双向链表初始化,请输入你要添加的元素个数!\n");
			scanf("%d",&n);
			while(n--)
			{
				int x;
				scanf("%d",&x);
				Insert_Dlist(head,x);
			}
			printf("完成建表操作!\n");
			break;
		case 2:                                  //新增操作
			if(!head)
			{
				printf("对不起,请先完成初始化操作再做该选择!!!\n");
				break;
			}
			printf("请输入你要添加的元素个数!\n");
			scanf("%d",&n);
			while(n--)
			{
				int x;
				scanf("%d",&x);
				Insert_Dlist(head,x);
			}
			printf("增添成功!\n");
			break;
		case 3:
			printf("请输入你所要删除的节点的位置:\n");
			scanf("%d",&n);
			Delete_Dlist(head,n);                             //删除操作
			break;
		case 4:
			printf("请输入你所要查找的元素:\n");
			scanf("%d",&m);
			Insearch_Dlist(head,m);                       //查找操作
			break;
		case 5:
			if(Empty_Dlist(head))
			{
				printf("对不起,链表是空的,无法完成修改操作!!!\n");
				break ;
			}
			printf("请输入你要更改的元素队列位置:\n");          //修改操作
			do{
				scanf("%d",&a);
				if(a<1||a>Length_Dlist(head))
					printf("对不起,你所输入的元素位置不在区域内,请重新输入!!!\n");
			}while(a<1||a>Length_Dlist(head));
			printf("请输入修改后的值:\n");
			scanf("%d",&b);
			Modify_Dlist(head,a,b);
			break;
		case 6:
			Destory_Dlist(head);            //销毁操作
			break;
		case 7:
			len1=Length_Dlist(head);             //返回链长操作
			printf("当前链队列的长度为:%d\n",len1);
			break;
		case 8:
			Print_Dlist(head);        //打印操作
			break;
		case 9:                   //退出操作
			return;
		default:
			instruction(head);
			break;
	}
	instruction(head);
}

时间: 2024-08-29 10:07:28

双向循环链表-C语言版的相关文章

从两端生长的双向栈-C语言版

<pre name="code" class="cpp">[cpp] 简单双端栈的应用 源文件部分: #include <stdio.h> #define MaxStackSize 100 typedef int DataType; int len,x; #include"SeqStack.h" int main() { SeqStack myStack; int i,n,m; StackInitiate(&myS

双向循环链表(C语言描述)(四)

下面以一个电子英汉词典程序(以下简称电子词典)为例,应用双向循环链表.分离数据结构,可以使逻辑代码独立于数据结构操作代码,程序结构更清晰,代码更简洁:电子词典的增.删.查.改操作分别对应于链表的插入.删除.查找.查找和获取链表元素操作. 在程序初始化时,除了初始化链表,还要将保存在文件中的词库加载到链表中: 1 void dict_init() { 2 list = linkedlist_new(); 3 4 dict_load(); 5 printf("Welcome."); 6 }

C语言通用双向循环链表操作函数集

说明 相比Linux内核链表宿主结构可有多个链表结构的优点,本函数集侧重封装性和易用性,而灵活性和效率有所降低.     可基于该函数集方便地构造栈或队列集.     本函数集暂未考虑并发保护. 一  概念 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序通过链表中的指针链接次序实现.链表由一系列存储结点组成,结点可在运行时动态生成.每个结点均由两部分组成,即存储数据元素的数据域和存储相邻结点地址的指针域.当进行插入或删除操作时,链表只需修改相关结点的指针域即可,因此相比线性

C语言双向循环链表api(源自gluster源码)

C语言双向循环链表api(源自gluster源码)基本的操作如增加.删除和遍历等 #include <stdio.h> #include <stdlib.h> #include <string.h> /*定义表头*/ struct list_head { struct list_head *next; struct list_head *prev; }; /*表头初始化*/ #define INIT_LIST_HEAD(head) do { (head)->nex

c语言编程之双向循环链表

双向循环链表就是形成两个环,注意每个环的首尾相连基本就可以了. 程序中采用尾插法进行添加节点. 1 #include<stdio.h> 2 #include<stdlib.h> 3 #define element int 4 typedef struct Node{ 5 element data; 6 struct Node *next; 7 struct Node *prior; 8 }*pNode; 9 10 //build a new double loop list 11

c语言双向循环链表

双向循环链表,先来说说双向链表,双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点.而循环链表之前也有说过,单链表中就是让最后一个结点的指针指向第一个结点就能构成一个循环链表,这里其实也是一样的,只不过多了一步,让第一个结点的前驱指向最后一个结点就行了,(这里介绍的是带头结点的双向循环链表,所以用第一个结点和头结点来区分两者).下面直接看看怎么创建一个带头结点的双向循环链表吧

C语言双向循环链表实现及图示(初始化/插入链表/清空/销毁)

-------------------------------------------- 双向循环链表 //遍历等执行方法与普通双向链表相同,不单独列举 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 初始化+尾插法 图示: 实现代码 1 /* 初始化

数据结构8: 双向链表(双向循环链表)的建立及C语言实现

之前接触到的链表都只有一个指针,指向直接后继,整个链表只能单方向从表头访问到表尾,这种结构的链表统称为 “单向链表”或“单链表”. 如果算法中需要频繁地找某结点的前趋结点,单链表的解决方式是遍历整个链表,增加算法的时间复杂度,影响整体效率.为了快速便捷地解决这类问题,在单向链表的基础上,给各个结点额外配备一个指针变量,用于指向每个结点的直接前趋元素.这样的链表被称为“双向链表”或者“双链表”. 双链表中的结点 双向链表中的结点有两个指针域,一个指向直接前趋,一个指向直接后继.(链表中第一个结点的

1.Go-copy函数、sort排序、双向链表、list操作和双向循环链表

1.1.copy函数 通过copy函数可以把一个切片内容复制到另一个切片中 (1)把长切片拷贝到短切片中 package main import "fmt" func main() { s1 := []int {1,2} s2 := []int{3,4,5,6} //copy的是角标,不会增加元切片的长度 copy(s1,s2) fmt.Println(s1) //[3 4] fmt.Println(s2) //[3 4 5 6] } (2)把短切片拷贝到长切片中 package ma