算法与数据结构之双向链表

直接看代码理解快一点,代码有些重要部分是有注释的。

#include<stdio.h>
#include<malloc.h>
#include<windows.h>
typedef int elemtype;
typedef struct dnode
{
elemtype data;
struct dnode *prior;
struct dnode *next;
}dlinklist;

void createlistf(dlinklist *&L,elemtype a[],int n) //建立双链表(头插法)
{
dlinklist *s;
int i;
L=(dlinklist *)malloc(sizeof(dlinklist));
L->prior=L->next=NULL;
for(i=0;i<n;i++)
{
s=(dlinklist *)malloc(sizeof(dlinklist));
s->data=a[i];
s->next=L->next;
if(L->next!=NULL)
L->next->prior=s;
L->next=s;
s->prior=L;
}
}

void creatlistr(dlinklist *&L,elemtype a[],int n) //尾插法建表
{
dlinklist *s,*p;
int i;
L=(dlinklist *)malloc(sizeof(dlinklist));
L->prior=L->next=NULL;
p=L;
for(i=0;i<n;i++)
{
s=(dlinklist *)malloc(sizeof(dlinklist));
s->data=a[i];
s->next=p->next;
p->next=s;
s->prior=p;
p=s;
s=p->next;
}
}

void listempty(dlinklist *L) //判断是否为空
{
if(L->next!=NULL)
printf("链表不为空\n");
else
printf("链表为空\n");
}
int listlength(dlinklist *L) //求链表长度
{
dlinklist *p=L;
int i=0;
while(p!=NULL)
{
i++;
p=p->next;
}
return i-1;
}

void listinsert(dlinklist *&L) //插入元素
{
dlinklist *p=L,*s;
int i,m,a;
printf("请输入需插入元素");
scanf("%d",&a);
printf("请输入需插入元素位置");
scanf("%d",&m);
if(m<0||m>listlength(L))
printf("输入错误\n");
else
{
for(i=0;i<m-1;i++)
p=p->next;
s=(dlinklist *)malloc(sizeof(dlinklist));
s->data=a;
s->next=p->next;
s->next->prior=s;
p->next=s;
s->prior=p;
printf("插入成功\n");
}
}

void listdelete(dlinklist *&L) //删除元素
{
dlinklist *p=L,*q;
int i,m,t;
printf("请输入需删除元素位置 ");
scanf("%d",&m);
if(m<0||m>listlength(L))
printf("输入错误\n");
else
{
for(i=0;i<m-1;i++)
p=p->next;
q=p->next;
p->next=q->next;
q->next->prior=p;
t=q->data;
free(q);
printf("成功删除元素%d\n",t);
}
}

void getelem(dlinklist *L) //取值
{
dlinklist *p=L;
int i=0,m;
printf("请输入取值元素 ");
scanf("%d",&m);
while(p!=NULL)
{
if(p->data==m)
printf("取值成功 %d元素在第%d位\n",m,i);
p=p->next;
i++;
}
if(p=NULL)
printf("没有此元素\n");
}

void locateelem(dlinklist *L) //查找
{
dlinklist *p=L;
int i=0,m;
printf("请输入需查找位置 ");
scanf("%d",&m);
if(m<=0||m>listlength(L))
printf("输入错误\n");
else
{
for(;i<m;i++)
p=p->next;
printf("第%d位的元素为%d\n",m,p->data);
}
}

void destroylist(dlinklist *&L) //销毁链表
{
dlinklist *p=L,*q;
char m;
getchar();
printf("确认要销毁链表请输入y否则不销毁 请输入:");
scanf("%c",&m);
if(m=='y')
{
q=p->next;
while(q!=NULL)
{
free(p);
p=q;
q=p->next;
}
free(p);
printf("链表已销毁\n");
exit(0);
}
printf("链表未销毁\n");
}

void displist(dlinklist *L) //输出双链表
{
dlinklist *s;
s=L->next;
while(s!=NULL)
{
printf(" %d",s->data);
s=s->next;
}
printf("\n");
}

void
main()
{

dlinklist *p;
int a[5],i,m,t;
printf("请选择建表方式 1用头插法建表,2用尾插法建表 ");
scanf("%d",&t);
printf("请输入5个数\n");
for(i=0;i<5;i++)
scanf("%d",&a[i]);
if(t==1)
createlistf(p,a,5);
else if(t==2)
creatlistr(p,a,5);
else
printf("输入错误!");
printf("双链表建立完毕\n");
while(1)
{
printf("请选择:");
printf(" 1.输出链表\n");
printf(" 2.判断线性表(双链表)是否为空\n");
printf(" 3.求线性表(双链表)的长度\n");
printf(" 4.从线性表(双链表)中取值\n");
printf(" 5.在线性表(双链表)中查找元素\n");
printf(" 6.插入元素\n");
printf(" 7.删除元素\n");
printf(" 8.销毁链表\n");
printf(" 9.退出\n");
scanf("%d",&m);
switch(m)
{ case 1:displist(p);break;
case 2:listempty(p);break;
case 3: printf("链表长为:%d\n",listlength(p));break;
case 4:getelem(p);break;
case 5:locateelem(p);break;
case 6:listinsert(p);break;
case 7:listdelete(p);break;
case 8:destroylist(p);break;
case 9:exit(0);
default:printf("输入错误,请重新输入\n");
}
}
}

时间: 2024-09-04 07:59:27

算法与数据结构之双向链表的相关文章

021_《Delphi算法与数据结构》

<Delphi算法与数据结构> Delphi 教程 系列书籍 (021) <Delphi算法与数据结构> 网友(邦)整理 EMail: shuaihj@163.com 下载地址: Pdf 附书源码     原书名: The Tomes of Delphi Algorithms and Data Structures 原出版社: Wordware Publishing 作者: [美]Julian Bucknall 译者: 林琪 朱涛江 丛书名: Delphi技术系列 出版社:中国电力

浅谈算法和数据结构 十一 哈希表

在前面的系列文章中,依次介绍了基于无序列表的顺序查找,基于有序数组的二分查找,平衡查找树,以及红黑树,下图是他们在平均以及最差情况下的时间复杂度: 可以看到在时间复杂度上,红黑树在平均情况下插入,查找以及删除上都达到了lgN的时间复杂度. 那么有没有查找效率更高的数据结构呢,答案就是本文接下来要介绍了散列表,也叫哈希表(Hash Table) 什么是哈希表 哈希表就是一种以 键-值(key-indexed) 存储数据的结构,我们只要输入待查找的值即key,即可查找到其对应的值. 哈希的思路很简单

浅谈算法和数据结构 三 合并排序

合并排序,顾名思义,就是通过将两个有序的序列合并为一个大的有序的序列的方式来实现排序.合并排序是一种典型的分治算法:首先将序列分为两部分,然后对每一部分进行循环递归的排序,然后逐个将结果进行合并. 合并排序最大的优点是它的时间复杂度为O(nlgn),这个是我们之前的选择排序和插入排序所达不到的.他还是一种稳定性排序,也就是相等的元素在序列中的相对位置在排序前后不会发生变化.他的唯一缺点是,需要利用额外的N的空间来进行排序. 一 原理 合并排序依赖于合并操作,即将两个已经排序的序列合并成一个序列,

浅谈算法和数据结构 二 基本排序算法

本篇开始学习排序算法.排序与我们日常生活中息息相关,比如,我们要从电话簿中找到某个联系人首先会按照姓氏排序.买火车票会按照出发时间或者时长排序.买东西会按照销量或者好评度排序.查找文件会按照修改时间排序等等.在计算机程序设计中,排序和查找也是最基本的算法,很多其他的算法都是以排序算法为基础,在一般的数据处理或分析中,通常第一步就是进行排序,比如说二分查找,首先要对数据进行排序.在Donald Knuth 的计算机程序设计的艺术这四卷书中,有一卷是专门介绍排序和查找的. 排序的算法有很多,在维基百

浅谈算法和数据结构 一 栈和队列

最近晚上在家里看Algorithems,4th Edition,我买的英文版,觉得这本书写的比较浅显易懂,而且"图码并茂",趁着这次机会打算好好学习做做笔记,这样也会印象深刻,这也是写这一系列文章的原因.另外普林斯顿大学在Coursera 上也有这本书同步的公开课,还有另外一门算法分析课,这门课程的作者也是这本书的作者,两门课都挺不错的. 计算机程序离不开算法和数据结构,本文简单介绍栈(Stack)和队列(Queue)的实现,.NET中与之相关的数据结构,典型应用等,希望能加深自己对这

字符串搜索-Boyer-Moore算法 《数据结构与算法c++版》Adam Drozdek

问题描述 Boyer-Moore算法 <数据结构与算法c++版>Adam Drozdek 通常BM算法采用的是坏字符和好后缀算法(eg.,BM算法),我学习的<数据结构与算法c++版>Adam Drozdek版教材上使用了 全后缀和部分后缀规则,这种方法在网络上基本查不到. 作者解释原理时,一个关键的函数只是给出公式,基本上没有解释,如下: 请问怎么理解这个公式,尤其是公式中的s代表什么意思? 原书我已经在云盘共享,关于BM算法书上在P687面.希望能帮忙解决.

求指点-求推荐:c,C++,算法,数据结构,编写简单游戏等方面的书籍。

问题描述 求推荐:c,C++,算法,数据结构,编写简单游戏等方面的书籍. 我是大一的,刚刚学完谭浩强的C,现在正在学开始谭浩强的C++.希望大家能够给一些建议:推荐一些书籍.谢谢 解决方案 说实话不推荐学习谭浩强的那两本书,别问为什么,因为你如果刚学的话,体会不到我说的,但是如果已经看完了,其实如果你只看了他的书的话,估计你啥也做不了,常见的C语言小程序,列入俄罗斯方块,贪吃蛇,扫雷,等等这些,不过提醒你,我给你你个关键词:1.函数 2.指针 3.链表 4.函数指针 5.数组 6.结构体 指针数

应届生-程序员面试,基本功重不重要(算法和数据结构)?

问题描述 程序员面试,基本功重不重要(算法和数据结构)? 无论是php还是移动应用开发等等,基本功在面试中占多大比重?面试该注意些什么? 解决方案 算法,数据结构是基础,有了基础,就能反映你的基本能力 不同开发方向,可能对这些要求高低不一样.比如php,移动开发等,应该这方面要求不会那么多,更侧重你有没有i相关经验 解决方案二: 基础工需要看你面试什么,一般语言类的会重视基础知识,应用类的会重视开发经验.面试应该注意态度要认真. 解决方案三: 基础工需要看你面试什么,一般语言类的会重视基础知识,

如何理解编程中最没用的东西是源代码,最有用的东西是算法和数据结构

问题描述 如何理解编程中最没用的东西是源代码,最有用的东西是算法和数据结构 编程中最没用的东西是源代码,最有用的东西是算法和数据结构 举个简单的算法和数据结构瞧瞧,谢谢 解决方案 这是胡扯,那微软的windows为什么不开源?说源代码没用的,把你的代码都开源啊. 解决方案二: 任何话都有上下文.这里不过是说,对于一个学习编程的人来说,学明白算法再看代码,比在你不懂算法的前提下看人家的代码有效率的多. 好比学习舞蹈,你需要的是学习分解动作,而不是直接模仿人家的姿势. 解决方案三: 算法和数据结构是