双向链表-C语言版

源文件部分:
#include<stdio.h>
#include<malloc.h>
#include<string.h>
typedef int Elemtype;
#include"DList.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 &arrow)    ///双向初始化
{
	arrow=(Dlnode)malloc(sizeof(DLnode));
	if(!arrow)
    {
        printf("对不起,已无更多的内存单元,初始化失败!\n");
        return ;
    }
	arrow->prior=NULL;
	arrow->next=NULL;
}

int Empty_Dlist(DLnode head)       ///双向判空
{
	if(head.next==NULL)
		return 1;
	return 0;
}

void Insert_Dlist(DLnode *head,Elemtype e)  ///尾插法-双向(新增)
{
	Dlnode p=NULL,q=head;
	p=(DLnode *)malloc(sizeof(DLnode));
	if(!p)
    {
        printf("对不起,已无更多的内存单元,申请内存失败!\n");
        return ;
    }
	while(q->next)
	{
		q=q->next;
	}
	p->data=e;
	p->next=NULL;
	p->prior=q;
	q->next=p;
}

int Length_Dlist(DLnode head)         ///双向的链长
{
	DLnode *p=NULL;
	int len=0;
	p=head.next;
	if(Empty_Dlist(head))
		return 0;
	while(p)
	{
		len++;
		p=p->next;
	}
	return len;
}

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

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)
	{
		if(p->data==e)
		{
			printf("你要查找的元素位于链表的第%d位置上.\n",len);
			return ;
		}
		len++;
		p=p->next;
	}
	printf("对不起,你要查找的元素不存在,请重新输入!!!\n");
	return ;
}

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

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

void Destory_Dlist(Dlnode head)            //双向的销毁-不包括头节点
{
	Dlnode p=head,q=NULL;
	while(p->next)
	{
		p=p->next;
	}
	while(p!=head)
	{
		p->prior->next=NULL;
		q=p;
		p=p->prior;
		free(q);
	}
	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:
			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-11-15 00:36:21

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

双向链表(c语言版)

为了得到一个简洁的C语言实现的双向链表,本篇参照数据结构书籍对双向链表的做了一些修改,内容有: 1.合并分离的头文件和实现文件,认识更为直观: 2.修改函数名和变量名,更贴近自身的理解: 3.删除了返回首节点.尾节点等功能更为单一的函数,留下其主干. 实现思路: 1.定义一个双向链表 2.进行初始化工作:调用initList(),构造一个空的双向链表 3.执行增删改查等操作(节点操作) *插入时注意:封装成节点 1 /*双向链表实现代码*/ 2 #include<malloc.h> 3 #in

《数据结构-C语言版》(严蔚敏,吴伟民版)课本源码+习题集解析使用说明

先附上文档归类目录: 课本源码合辑  链接??? <数据结构>课本源码合辑 习题集全解析  链接??? <数据结构题集>习题解析合辑 博主有话说: 01.自学编程,难免思路阻塞,所以从今天起,我(StrayedKing)决定在本博客陆续更新严蔚敏,吴伟民版<数据结构-C语言版>各章节的课本源码和配套习题集答案解析,目的是为了整理数据结构中的知识点,并与网友交流意见,集思广益,共同进步.        ★注★ 左侧随笔分类下用两个栏目:<课本源码>.<习

人事管理系统 c语言版

int menu(){ printf("请按提示输入完成操作!\n"); printf("1.查询员工信息\n"); printf("2.统计员工数量\n"); printf("3.录入员工信息\n"); printf("4.删除员工信息\n"); printf("5.按id排序所有员工\n"); printf("6.打印所有员工信息\n"); printf(&quo

排序算法总结(C语言版)

1.    插入排序 1.1     直接插入排序 1.2     Shell排序 2.    交换排序 2.1     冒泡排序 2.2     快速排序 3.    选择排序 3.1     直接选择排序 3.2     堆排序 4.    归并排序 4.1     二路归并排序 4.2     自然合并排序 5.    分布排序 5.1     基数排序 1.插入排序 1.1      直接插入排序 将已排好序的部分num[0]~num[i]后的一个元素num[i+1]插入到之前已排好序的

51系列小型操作系统精髓 简单实现8 C语言版待改进

使用keil4  ,代码Code Optimization:0   运行OK 可运行8个任务 Program Size: data=21.0 xdata=0 code=401  (包括2个示例变量,未优化) 任务从中断处切换,在定时时间到后从定时中断中切换回来. 待改进地方 1.手动优化汇编程序 2. 重入问题 3.参数进函数和时中断的保护问题 #include "STC12C5A.H" #define TIMER_RELOAD()  {TL0=0x00;TH0=0xC4;}//使能T

51系列小型操作系统精髓 简单实现11 C语言版优化后说明(有图)

/* CRTOS 实时可剥夺型内核 1.任务不用预加载,不用预定义.任务调用时加载,可删除(退出死循环即可) 2.单位轮转查询时间由晶振和定时器初始化决定.在这里为10ms 3.定时时间为[ time*单位轮转查询时间 ] ,其中time为 rtos_wait(time)中time. 4.可运行多个任务[自定义] 5.任务从rtos_wait()处切换,在定时时间到后从定时中断中切换回来,任务执行后,回到中断,再从中断回到主程序. */ #include "STC12C5A.H" #d

51系列小型操作系统精髓 简单实现7 C语言版待改进

#include "STC12C5A.H" #define TIMER_RELOAD()  {TL0=0x00;TH0=0xC4;}//使能T/C  初始10ms #define MAX_TASKS 2 //任务槽最大个数. unsigned char idata task_stack[MAX_TASKS][2];//任务堆栈.  PC指针为16位,需2个字节task_stack[][0]L  task_stack[][1]H. unsigned char idata task_tim

2048小游戏(C语言版)

1 #include <climits> 2 #include <cstdio> 3 #include <cstring> 4 #include <stack> 5 #include <string> 6 #include <map> 7 #include <vector> 8 #include <cmath> 9 10 11 /* 12 玩法说明:编译运行后,输入一个整数n,表示自己想玩的游戏中是n*n的表格

(续)线性表之双向链表(C语言实现)

在前文实现单向链表的基本操作下,本文实现 双向链表的基本操作. 双向链表与单链表差异,是双向链表结点中有前向指针和后向指针. 所以在插入和删除新结点元素时候不见要考虑后向指针还要考虑 前向指针. 以下是双向链表的C代码: #include<stdio.h> typedef struct node { int data; struct node *next; struct node *prior }Node; //链表的初始化 Node* InitList(int number) { int i