双向链表的创建和相关操作
http://blog.csdn.net/jw903/article/details/38947753
双向链表其实是单链表的改进。 当我们对单链表进行操作时,有时你要对某个结点的直接前驱进行操作时,又必须从表头开始查找。这是由单链表结点的结构所限制的。因为单链表每个结点只有一个存储直接后继结点地址的链域,那么能不能定义一个既有存储直接后继结点地址的链域,又有存储直接前驱结点地址的链域的这样一个双链域结点结构呢?这就是双向链表。
在双向链表中,结点除含有数据域外,还有两个链域,一个存储直接后继结点地址,一般称之为右链域;一个存储直接前驱结点地址,一般称之为左链域。
在c语言中双向链表结点类型可以定义为:
- typedef struct Node
- {
- int item;
- struct Node *pre;
- struct Node *next;
- }DListNode,*DList;
下面的代码就是对双向链表的创建和相关操作:
- /***************************************************************************
- *name:jae chia *
- *date:2014.8.29 *
- *version: 1.0 *
- **************************************************************************/
- #include<iostream>
- #include<cassert>
- using namespace std;
- //双向链表的建立与操作
- typedef struct Node
- {
- int item;
- struct Node *pre;
- struct Node *next;
- }DListNode,*DList;
- DList InsertNodeToTail(DList head,int data)//将节点插入到双向链表的尾部
- {
- if(head==NULL)
- {
- head=(DList)malloc(sizeof(DListNode));
- assert(head!=NULL);
- head->item=data;
- head->next=NULL;
- head->pre=NULL;
- }
- else
- {
- DListNode *newnode=(DList)malloc(sizeof(DListNode));//创建新的链表节点
- assert(newnode!=NULL);
- newnode->item=data;
- newnode->next=NULL;
- newnode->pre=NULL;
- DListNode *p=head;
- while(p->next!=NULL)
- {
- p=p->next;
- }
- p->next=newnode;
- newnode->pre=p;
- }
- return head;
- }
- DList InsertDListByOrder(DList head,int data)//这里的插入操作是按序插入(保证双向链表中的节点以递增有序)
- {
- DListNode *newnode=(DList)malloc(sizeof(DListNode));
- assert(newnode);
- newnode->item=data;
- //newnode->next=NULL;
- //newnode->pre=NULL;
- DListNode *p=head;
- DListNode *prenode;
- for(;p!=NULL;p=p->next)
- {
- prenode=p;
- if(newnode->item <=p->item)
- break;
- }
- if(p==NULL)//如果遍历整个链表,结点的值都比要插入的小,那么只能在尾端插入
- {
- prenode->next=newnode;
- newnode->pre=prenode;
- newnode->next=NULL;
- }
- else if(p==head)//如果链表中的数都比要插入的数大则在头部插入;
- {
- newnode->pre=NULL;
- newnode->next=head;
- head=newnode;
- }
- else //在中间插入
- {
- p->pre->next=newnode;
- newnode->pre=p->pre;
- newnode->next=p;
- p->pre=newnode;
- }
- return head;
- }
- bool FindNode(DList head,int data)//查找链表中含有某元素的节点是否存在
- {
- if(head==NULL)
- {
- cout<<"the Dlist is NULL"<<endl;
- return false;
- }
- DListNode *p=head;
- while(p!=NULL)
- {
- if(p->item==data)
- return true;
- p=p->next;
- }
- return false;
- }
- DList DeleteNode(DList head,int data)//删除节点
- {
- DListNode *p=head;
- while(p!=NULL)
- {
- if(p->item==data)
- break;
- p=p->next;
- }
- if(p==NULL)
- {
- cout<<"the node with data is not existed in the List"<<endl;
- exit(0);
- }
- if(p==head)//要删除的结点恰好是双向链表的头结点
- {
- DListNode *tmp=head;
- head=head->next;
- head->pre=NULL;//---------------------------------------------------
- free(tmp);
- }
- else if(p->next==NULL)//如果要删除的节点是链表的最后一个节点
- {
- p->pre->next=NULL;
- free(p);
- }
- else //删除中间节点
- {
- p->pre->next=p->next;
- p->next->pre=p->pre;
- }
- return head;
- }
- void PrintDList(DList head)//打印
- {
- cout<<"现在,链表如下:"<<endl;
- if(head==NULL)
- {
- cout<<"the Dlist is NULL"<<endl;
- return ;
- }
- DListNode *p=head;
- while(p!=NULL)
- {
- cout<<p->item<<" ";
- p=p->next;
- }
- cout<<endl<<endl;
- }
- void DestroyDList(DList head)//销毁双向链表
- {
- DListNode *p=head;
- while(p!=NULL)
- {
- DListNode *tmp=p;
- p=p->next;
- free(tmp);
- }
- }
- void Test()
- {
- DListNode *head=NULL;
- for(int i=0;i<10;i++) /*利用尾部插入来构造双向链表*/
- head=InsertNodeToTail(head,i);
- PrintDList(head);
- int a;
- cout<<"输入要查找的结点的值"<<endl;
- cin>>a;
- if(FindNode(head,a))
- cout<<"结点存在!"<<endl<<endl;
- else
- cout<<"结点不存在!"<<endl<<endl;
- cout<<"删除结点4..."<<endl; /*删除指定节点*/
- head=DeleteNode(head,4);
- PrintDList(head);
- cout<<"插入结点4..."<<endl; /*按序插入*/
- head=InsertDListByOrder(head,4);
- PrintDList(head);
- cout<<"删除头结点..."<<endl; /*删除指定节点*/
- head=DeleteNode(head,0);
- PrintDList(head);
- cout<<"删除尾结点..."<<endl;
- head=DeleteNode(head,9);
- PrintDList(head);
- cout<<"插入头结点..."<<endl; /*按序插入*/
- head=InsertDListByOrder(head,0);
- PrintDList(head);
- cout<<"插入尾结点..."<<endl; /*按序插入*/
- head=InsertDListByOrder(head,10);
- PrintDList(head);
- DestroyDList(head);
- }
- int main(void)
- {
- Test();
- }
运行:
双向链表的创建和相关操作相关推荐
- ORCL创建用户相关操作
ORCL创建用户相关操作 -- 0.查询表空间文件保存路径 select * from v$datafile --1. 创建表空间 create tablespace jcsjv1 datafile ...
- 关于学习Python的一点学习总结(9->字典创建及相关操作)
27.创建和使用字典:字典由键及其相应的值组成,这种键值对称为项(item) 方法一: >>> name={'Hongkong':'45','shanghai':'67','gui ...
- 数据结构--二叉树的创建和相关操作
下面给出两个关于二叉树的题目: 1.编写程序任意输入二叉树的结点个数和结点值,构造一棵二叉树,采用三种递归遍历算法(前序.中序.后序)对这棵二叉树进行遍历并计算出二叉树的高度. 2 .编写程序生成下面 ...
- 数据结构——双向链表(双向连接的图解、双向链表的创建、操作双向链表)
目录 一.双向链表 二.双向连接的图解: 三.双向链表的创建 四.操作双向链表 一.双向链表 - 单向链表: - 只能从头遍历到尾或者从尾遍历到头(一般从头到尾) - 也就是链表相连的过程是单向的 ...
- (C++版)链表(一)——实现单向链表创建、插入、删除等相关操作
http://blog.csdn.net/fisherwan/article/details/25557545 前段时间用C语言实现了链表的相关操作,但是发现当时挺清楚的,过了一段时间又忘的差不多了, ...
- 数据库MySQL相关操作||创建数据库、显示所有数据库、切换数据库、显示数据库下的数据库表、删除数据库
数据库MySQL相关操作||创建数据库.显示所有数据库.切换数据库.显示数据库下的数据库表.删除数据库 1,创建数据库 create databases mydb: 记得加:(分号) 2,显示所有数据 ...
- Linux系统编程10:进程入门之系统编程中最重要的概念之进程进程的相关操作使用fork创建进程
文章目录 (1)进程的概念 (2)如何管理进程 A:描述 B:PCB C:task_struct (3)进程相关操作 A:查看进程 B:进程与父进程 (4)创建进程-fork A:fork的作用:演示 ...
- 【环境搭建】Docker镜像相关操作(切换镜像源、查询、获取、查看、创建、上传、保存、删除等)
目录 1 镜像源查看及设置 2 镜像相关操作 2.1 获取镜像列表 2.2 镜像下载 2.3 查看本地的镜像 2.4 从镜像创建容器 2.5 将容器抽象为镜像--commit 2.6 将容器抽象为镜像 ...
- 建工计算机在线使用,建工计算器创建公式的相关操作教程
很多新手小伙伴还不了解建工计算器创建公式的具体操作,所以下面小编就带来了建工计算器创建公式的详细教程哦. 建工计算器创建公式的相关操作教程 1. 以"2点之间的距离"为例,首先点击 ...
最新文章
- python 调用 so 库 需要注意的地方
- JS----click3种方法
- Android存储Json到本地,和读取本地Json
- Linux 下的DMA浅析
- python enumerate()
- Ubuntu开发者峰会在布拉格举行
- 南丁格尔邮票图片大全_【鉴赏】武夷山普通纪念币鉴赏(高清图片)
- python游戏编程讲解之凯撒密码
- 3V升压5V芯片,3V升压5V电路图
- iOS 禁止横屏的解决方案
- A*算法————传教士和野人
- 在linux4.19内核下的UPD720201驱动里添加固件下载的代码
- 最完整的PS快捷键大全(绝对经典)
- 保温杯哪种材质最好_玻璃杯材质分为哪几种 玻璃杯什么材质最好
- 添加额外jars包到Hive
- Java字节码角度分析:Synchronized ——提升硬实力11
- mysql 分段执行_mySql 分段查询
- Redmine3.3.3 搭建与不完全填坑指南
- Linux·信号量全解
- 课程笔记之《论文写作》