ch2-23-双链表存储及运算实现代码

合集下载

链表的基本操作代码c语言

链表的基本操作代码c语言

链表的基本操作代码c语言链表是一种常见的数据结构,其基本操作包括创建、插入、删除和遍历等。

以下是链表的基本操作代码(C语言实现):1. 链表节点的定义cCopy codetypedef struct ListNode { int val; // 节点的值struct ListNode *next; // 指向下一个节点的指针 } ListNode;2. 创建链表cCopy codeListNode* createList(int arr[], int n) { ListNode *head = NULL, *tail = NULL; for (int i = 0; i < n; i++) { ListNode *node = (ListNode *)malloc(sizeof(ListNode)); node->val = arr[i]; node->next = NULL; if (tail == NULL) { head = tail = node; } else { tail->next = node; tail = node; } } return head; }3. 插入节点cCopy codevoid insertNode(ListNode **head, int val, int index) { if (index < 0) { return; } ListNode *node = (ListNode *)malloc(sizeof(ListNode)); node->val = val; node->next = NULL; if (index == 0) { node->next = *head; *head = node; } else { ListNode *prev = *head; for (int i = 0; i < index - 1; i++) { if (prev == NULL) { return; } prev = prev->next; }if (prev == NULL) { return; } node->next = prev->next; prev->next = node; } }4. 删除节点cCopy codevoid deleteNode(ListNode **head, int index) { if (*head == NULL || index < 0) { return; } if (index == 0) { ListNode *node = *head; *head = (*head)->next; free(node); } else { ListNode *prev = *head; for (int i = 0; i < index - 1; i++) { if (prev->next == NULL) { return; } prev = prev->next; } if (prev->next == NULL) { return; } ListNode *node = prev->next; prev->next = node->next; free(node); } }5. 遍历链表cCopy codevoid traverseList(ListNode *head) { while (head != NULL) { printf("%d ", head->val); head = head->next; } printf("\n"); }以上是链表的基本操作代码,可以根据需要进行调整和扩展。

双向链表的算法设计与实现实验报告

双向链表的算法设计与实现实验报告

数学与计算科学学院实验报告
实验项目名称双向链表的算法设计与实现
所属课程名称__数据结构A
实验类型设计型
实验日期__
班级信计1402
学号201453100214
姓名俞凯烨
成绩
【实验小结】(收获体会)
附录1:源程序
附录2:实验报告填写说明
1.实验项目名称:要求与实验教学大纲一致。

2.实验目的:目的要明确,要抓住重点,符合实验教学大纲要求。

3.实验原理:简要说明本实验项目所涉及的理论知识。

4.实验环境:实验用的软、硬件环境。

5.实验方案(思路、步骤和方法等):这是实验报告极其重要的内容。

概括整个实验过程。

对于验证性实验,要写明依据何种原理、操作方法进行实验,要写明需要经过哪几个步骤来实现其操作。

对于设计性和综合性实验,在上述内容基础上还应该画出流程图、设计思路和设计方法,再配以相应的文字说明。

对于创新性实验,还应注明其创新点、特色。

6.实验过程(实验中涉及的记录、数据、分析):写明具体实验方案的具体实施步骤,包括实验过程中的记录、数据和相应的分析。

7.实验结论(结果):根据实验过程中得到的结果,做出结论。

8.实验小结:本次实验心得体会、思考和建议。

9.指导教师评语及成绩:指导教师依据学生的实际报告内容,给出本次实验报告的评价。

实现双向链表的基本操作

实现双向链表的基本操作

一、什么是双向链表双向链表,也称双向链式线性表,是一种常见的数据结构,它由多个节点组成,每个节点都包含指向前一个节点和后一个节点的指针。

与单向链表不同的是,双向链表的每个节点都有两个指针,这样可以在不遍历整个链表的情况下,方便地访问任何一个节点。

二、基本操作1. 初始化初始化双向链表需要定义一个头节点,该节点不存储实际数据,只用于标记链表的开始位置。

头节点的前驱指针和后继指针都指向NULL ,表示链表为空。

2. 插入节点插入节点是双向链表最常见的操作,它分为三种情况:在链表头部插入、在链表尾部插入和在链表中间插入。

头部插入:先创建一个新节点,并将该节点的后继指针指向当前头节点,将头节点的前驱指针指向新节点,再将链表的头节点指向新节点,完成插入。

尾部插入:先找到链表的尾节点,再创建一个新节点,并将新节点的前驱指针指向当前尾节点,将尾节点的后继指针指向新节点,再将新节点的后继指针指向 NULL ,完成插入。

中间插入:先找到要插入节点的位置,即该节点前一个节点的后继指针和后一个节点的前驱指针,分别指向新节点。

新节点的前驱指针指向前一个节点,后继指针指向后一个节点,完成插入。

3. 删除节点删除节点也分为三种情况:删除头节点、删除尾节点和删除中间节点。

头节点删除:将头节点的后继节点作为新的头节点,将新头节点的前驱指针指向 NULL ,完成删除。

尾节点删除:将尾节点的前驱节点作为新的尾节点,将新尾节点的后继指针指向 NULL ,完成删除。

中间节点删除:先找到要删除节点的位置,即该节点前一个节点的后继指针和后一个节点的前驱指针,分别指向该节点的前一个节点和后一个节点,完成删除。

4. 查找节点查找节点可以通过遍历链表来实现,在双向链表中,由于每个节点都有前驱和后继指针,因此可以从前向后或从后向前进行查找。

需要注意的是,由于双向链表的查找操作需要遍历整个链表,因此效率较低,不适用于大规模数据的查找。

5. 输出链表输出链表可以通过遍历链表来实现,从头节点开始,依次输出每个节点的数据。

C语言学习-双链表(LinkList)数据结构类型

C语言学习-双链表(LinkList)数据结构类型

C语⾔学习-双链表(LinkList)数据结构类型双向链表是链表中的⼀种,双链表是操作系统中常⽤的数据结构,其特点就是,每个链表节点都具有两个指向同类型数据结构的指针变量成员。

双向链表的节点的数据结构类型模型代表:1struct p_list_node2 {3struct p_list_node *p_next; //指向后继节点4struct p_list_node *p_prev; //指向前置节点5 };给已有的结构体数据类型起⼀个容易理解识别的别名:1 typedef struct p_list_node p_list;###双向链表的初始化函数:1void rt_list_init(p_list *l)2 {3 l->p_next = l->p_prev = l;4 }双向链表的初始化,就是让链表节点的成员指针指向本节点⾃⼰。

###双向链表中,向指定节点后⾯插⼊节点⽅法:1void rt_list_insert_after(p_list *l,p_list *n)2 {3 l->p_next->p_prev = n; //先让指定节点的后继节点指向新插⼊的节点4 n->p_next = l->p_next; //再让新插⼊的节点指向它⾃⼰的后继节点56 l->p_next = n; //让指定节点指向新插⼊的节点7 n->p_prev = l; //让新插⼊的节点指向指定节点8 }思维⽅式:后插法,先让新节点和指定节点的后继节点建⽴指向关系,再让新插⼊节点和指定节点建⽴指向关系。

###双向链表中,向指定节点前⾯插⼊节点⽅法:1void rt_list_insert_before(p_list *l,p_list *n)2 {3 l->p_prev->p_next = n; //先让指定节点的前置节点指向新插⼊的节点4 n->p_prev = l->p_prev; //再让新插⼊的节点指向指定节点的前置节点56 l->p_prev = n; //让指定节点指向新插⼊的节点7 n->p_next = l; //在让新插⼊的节点指向指定节点8 }思维⽅式:前插法,先让新节点和指定节点的前置节点建⽴指向关系,再让新插⼊节点和指定节点建⽴指向关系。

数据结构之双向链表的Java实现

数据结构之双向链表的Java实现

数据结构之双向链表地Java 实现单链表只能从前往后遍历,如果链表地长度较大, 遍历到链表后半部分地时候想要往前查找,就只能回到开头,重新遍历了.双向链表提供了这个能力, 即允许前向遍历, 也允许后向遍历整个链表. 原因是双向链表地每个节点都有两个指向其他节点地引用. 但这也是其缺点, 因为在插入、删除地时候需要处理四个链接点地引用, 占用地空间也大了一些. 如将头节点和尾节点链接起来, 即成为双向循环链表. b5E2RGbCAP下面是java 代码:package test 。

public class DoubleLink {public Link first 。

public Link last 。

public DoubleLink< ) {// 构造器, 初始化this.first = null 。

st = null 。

}public boolean isEmpty< ) {// 判断是否为空return first == null 。

}public void insertFirst<int idata ) {// 将元素插入链表开头Link link = new Link<idata );if <isEmpty< ))last = link 。

// 如果为空,last 需要改变elselink.next = first 。

first = link 。

}public void insertLast<int idata ){// 插入链表结尾Link link = new Link<idata );if <isEmpty< ))first = link 。

elselast.next = link 。

link.previous = last 。

last = link 。

}public boolean insertAfter<int key, int idata在某项元素后) {//插入p1EanqFDPwLink current = first 。

c++双向链表操作示例(创建双向链、双向链表中查找数据、插入数据等)

c++双向链表操作示例(创建双向链、双向链表中查找数据、插入数据等)

c++双向链表操作⽰例(创建双向链、双向链表中查找数据、插⼊数据等)双向链表也叫双链表,是链表的⼀种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。

所以,从双向链表中的任意⼀个结点开始,都可以很⽅便地访问它的前驱结点和后继结点。

⼀般我们都构造双向循环链表。

(1)定义双向链表的基本结构复制代码代码如下:typedef struct _DOUBLE_LINK_NODE{int data;struct _DOUBLE_LINK_NODE* prev;struct _DOUBLE_LINK_NODE* next;}DOUBLE_LINK_NODE;(2)创建双向链表节点复制代码代码如下:DOUBLE_LINK_NODE* create_double_link_node(int value){DOUBLE_LINK_NODE* pDLinkNode = NULL;pDLinkNode = (DOUBLE_LINK_NODE*)malloc(sizeof(DOUBLE_LINK_NODE));assert(NULL != pDLinkNode);memset(pDLinkNode, 0, sizeof(DOUBLE_LINK_NODE));pDLinkNode->data = value;return pDLinkNode;}(3)删除双向链表复制代码代码如下:void delete_all_double_link_node(DOUBLE_LINK_NODE** pDLinkNode){DOUBLE_LINK_NODE* pNode;if(NULL == *pDLinkNode)return ;pNode = *pDLinkNode;*pDLinkNode = pNode->next;free(pNode);delete_all_double_link_node(pDLinkNode);}(4)在双向链表中查找数据复制代码代码如下:DOUBLE_LINK_NODE* find_data_in_double_link(const DOUBLE_LINK_NODE* pDLinkNode, int data){DOUBLE_LINK_NODE* pNode = NULL;if(NULL == pDLinkNode)return NULL;pNode = (DOUBLE_LINK_NODE*)pDLinkNode;while(NULL != pNode){if(data == pNode->data)return pNode;pNode = pNode ->next;}return NULL;}(5)双向链表中插⼊数据复制代码代码如下:STATUS insert_data_into_double_link(DOUBLE_LINK_NODE** ppDLinkNode, int data) {DOUBLE_LINK_NODE* pNode;DOUBLE_LINK_NODE* pIndex;if(NULL == ppDLinkNode)return FALSE;if(NULL == *ppDLinkNode){pNode = create_double_link_node(data);assert(NULL != pNode);*ppDLinkNode = pNode;(*ppDLinkNode)->prev = (*ppDLinkNode)->next = NULL;return TRUE;}if(NULL != find_data_in_double_link(*ppDLinkNode, data))return FALSE;pNode = create_double_link_node(data);assert(NULL != pNode);pIndex = *ppDLinkNode;while(NULL != pIndex->next)pIndex = pIndex->next;pNode->prev = pIndex;pNode->next = pIndex->next;pIndex->next = pNode;return TRUE;}(6)双向链表中删除数据复制代码代码如下:STATUS delete_data_from_double_link(DOUBLE_LINK_NODE** ppDLinkNode, int data) {DOUBLE_LINK_NODE* pNode;if(NULL == ppDLinkNode || NULL == *ppDLinkNode)return FALSE;pNode = find_data_in_double_link(*ppDLinkNode, data);if(NULL == pNode)return FALSE;if(pNode == *ppDLinkNode){if(NULL == (*ppDLinkNode)->next){*ppDLinkNode = NULL;}else{*ppDLinkNode = pNode->next;(*ppDLinkNode)->prev = NULL;}}else{if(pNode->next)pNode->next->prev = pNode->prev;pNode->prev->next = pNode->next;}free(pNode);return TRUE;}(7)统计双向链表中数据的个数复制代码代码如下:int count_number_in_double_link(const DOUBLE_LINK_NODE* pDLinkNode){int count = 0;DOUBLE_LINK_NODE* pNode = (DOUBLE_LINK_NODE*)pDLinkNode;while(NULL != pNode){count ++;pNode = pNode->next;}return count;}(8)打印双向链表中数据复制代码代码如下:void print_double_link_node(const DOUBLE_LINK_NODE* pDLinkNode){DOUBLE_LINK_NODE* pNode = (DOUBLE_LINK_NODE*)pDLinkNode;while(NULL != pNode){printf("%d\n", pNode->data);pNode = pNode ->next;}}今天我们讨论的双向链表是⾮循环的,⼤家可以考虑⼀下如果改成循环双向链表,应该怎么写?如果是有序的循环双向链表,⼜该怎么写?。

数据结构双链表实现代码

数据结构双链表实现代码

数据结构双链表实现函数#include <stdlib.h>#include <stdio.h>/*――――――――――――双向链表的定义――――――――――――*/struct llist{struct llist *prior;int num;struct llist *next;};typedef struct llist node;typedef node *llink;/*――――――――――――双向链表的输出――――――――――――*/void printllist(llink head){llink ptr;ptr = head->next;while ( ptr != NULL ){printf("[%d]",ptr->num);ptr = ptr->next;}printf("\n");}/*――――――――――――双向链表的倒序输出――――――――――*/void printllist2(llink head){llink ptr;ptr = head;while( ptr->next != NULL ){ptr=ptr->next;}while ( ptr != head ){printf("[%d]",ptr->num);ptr = ptr->prior;}printf("\n");}/*――――――――――――双向链表的创建―――――――――――*/llink createllist(int *array,int len){llink head; /* 双向链表的开始指针*/llink ptr,ptr1;int i;/* 建立开头结点*/head = ( llink ) malloc(sizeof(node)); /* 分配内存*/if ( !head ) /* 检查指针*/return NULL;ptr = head;/* 将ptr指向链表开始*/for ( i = 0; i < len; i++ ) /* 建立其它结点回路*/{ptr1 = ( llink ) malloc(sizeof(node));if ( !ptr1 )return NULL;ptr1->num = array[i]; /* 建立结点内容*/ptr1->next = NULL; /* 设定指针初值*/ptr1->prior = NULL;ptr->next = ptr1; /* 连接结点*/ptr1->prior = ptr;ptr = ptr->next;}return head;}/*―――――――――――双向链表的结点插入――――――――――*/llink insertnode(llink head,llink ptr,int value){llink new1,ptr1=head; /* 新结点指针变量*/while(ptr1!=ptr)ptr1=ptr1->next;if(!ptr1){printf("找不到插入位置,插入位置有误\n");return head;}new1= ( llink ) malloc(sizeof(node));if ( !new1 )return NULL;new1->num = value; /* 设定初值*/new1->next = NULL;new1->prior = NULL;new1->next = ptr->next;/* 交换4个指针*/ptr->next->prior = new1;ptr->next = new1;new1->prior = ptr;return head;/* 返回头结点*/}/*―――――――――――双向链表的结点删除――――――――――-*/ llink deletenode(llink head,llink ptr){if(!(head->next)) {/* 链表为空直接返回头指针*/printf("删除链表为空\n");return head;}llink previous;previous = head;if(ptr){while ( previous->next != ptr ) /* 找结点ptr前一结点*/previous = previous->next;/* 找结点ptr前一结点之后进行删除操作*/previous->next = ptr->next;ptr->next->prior=previous; /* 删除中间结点*/}else{while ( previous->next->next != NULL )previous = previous->next;ptr= previous->next;previous->next = ptr->next;}free(ptr);return head;/* 返回头结点*/}/*―――――――――――――主程序――――――――――――――*/ void main(){int llist1[6] = { 1, 2, 3, 4, 5, 6 };llink head;/* 建立链表并输出*/head = createllist(llist1,6);if ( !head ){printf("内存分配失败! \n");exit(1);}printf("原来的链表: ");printllist(head);/* 插入新结点(在表头插入元素"0")*/head = insertnode(head,head,0);if ( !head ){printf("内存分配失败! \n");exit(1);}printf("插入结点后的链表: ");printllist(head);/* 删除链内结点(删除第三个结点) */head = deletenode(head,head->next->next->next);printf("删除结点后的链表: ");printllist(head);/* 倒序输出链表元素*/printf("链表的倒序输出: ");printllist2(head);}/*―――――――――――――结束――――――――――――――*/。

C语言数据结构双链表源代码

C语言数据结构双链表源代码
/* i 的合法长度为 1<=n<=表长 */ /* 当返回值为零的时候表示通不过合法性审查 */ int n,j=1; Link p; p=l->head; n=l->len; if(i<1&&i>n){printf("now!!");return 0;} for(;j<i;j++){ p=p->next; } p->prior->next=p->next; p->next->prior=p->prior; l->len=(l->len-1); if(i==l->len)l->tail=p->prior; if(i==1)l->head=p->next; free(p); return 1; } /*****************************************************************************/ Sort(int n,int *elem) /* 为了保持表的有序,将输入保存在线性表中 */ /* 先用插入排序法排序好后再创建双链表 */ { int i,j;
帖请注明,做人要厚道 ******************************************************************************/
#include <stdio.h> typedef struct LNode{
int data; struct LNode *next; struct LNode *prior; }*Link,Position;
/* 1<=n<=表长+1 */

c++中双链表的用法

c++中双链表的用法

c++中双链表的用法在C++中,双链表是一种常用的数据结构,它由一系列节点组成,每个节点包含两个部分:数据和指向下一个节点的指针。

双链表可以用来存储具有顺序关系的数据,并且可以在常数时间内完成插入、删除和查找等操作。

以下是使用C++实现双链表的基本步骤:1. 定义节点结构体```c++struct Node {int data;Node* next;};```2. 创建双链表类```c++class LinkedList {private:Node* head;public:LinkedList() {head = nullptr;}// 添加节点到链表末尾void addNode(int data) {Node* newNode = new Node();newNode->data = data;newNode->next = nullptr;if (head == nullptr) {head = newNode;} else {Node* temp = head;while (temp->next != nullptr) {temp = temp->next;}temp->next = newNode;}}// 删除指定数据的节点void removeNode(int data) {if (head == nullptr) {return;}if (head->data == data) {head = head->next;delete temp;return;}Node* prev = head;Node* curr = head->next;while (curr != nullptr && curr->data != data) { prev = curr;curr = curr->next;}if (curr == nullptr) {return;}prev->next = curr->next;delete curr;}// 打印链表中的数据void printList() {Node* temp = head;while (temp != nullptr) {cout << temp->data << " ";}cout << endl;}};```。

二叉树的二叉链表存储及基本操作

二叉树的二叉链表存储及基本操作

二叉树的二叉链表存储及基本操作《二叉树的二叉链表存储及基本操作》一、二叉树的二叉链表表示及存储1.定义二叉树的二叉链表存储表示是把一个二叉树存放在计算机中的一种表示形式,它是由一组以结点对象为元素的链表构成的,结点对象中包括数据域和结构域。

数据域存放结点的数据元素;结构域由两个指针域组成,其中一个指向左孩子,另一个指向右孩子。

2.存储形式二叉树的二叉链表存储表示可以用如下的存储形式表示:typedef struct BTNode {TElemType data; // 结点的数据域struct BTNode *lchild; // 指向左孩子的指针域struct BTNode *rchild; // 指向右孩子的指针域} BTNode; // 树结点的定义typedef BTNode *BiTree; // 定义二叉树的指针类型3.空的二叉树把一个指向树结点的指针设为NULL,称为一个空的二叉树。

一般在某个树被销毁后,都要把该树设置成空树。

二、二叉树的基本操作1.求二叉树的结点数要求二叉树的结点数,可以用递归的方法求解。

求n个结点的二叉树的结点数,可以先求出它的左子树结点数,右子树结点数,再加上根结点的数量就得到了结点数。

// 求二叉树的结点数int CountBTNode(BiTree T){if (T == NULL) // 空树,结点数为0return 0;else // 左子树结点数 + 右子树结点数 + 1return CountBTNode(T -> lchild) + CountBTNode(T -> rchild) + 1;}2.求二叉树叶结点数要求二叉树叶结点数,也可以用递归的方法求解。

当一个结点的左子树为空树,右子树也为空树时,它就是一个叶结点,则叶结点数加1;如果结点不是叶结点,则继续求它的左子树叶结点数和右子树叶结点数,再把它们加起来就是该二叉树的叶结点数。

// 求二叉树叶结点数int CountBTLeaf(BiTree T){if (T == NULL) // 空树,叶结点数为0return 0;else if (T -> lchild == NULL && T -> rchild == NULL) //判读是否是叶结点return 1;else // 左子树叶结点数 + 右子树叶结点数return CountBTLeaf(T -> lchild) + CountBTLeaf(T -> rchild);}3.求二叉树深度要求二叉树深度,也可以用递归的方法求解。

双向链表基本操作及代码优化技巧

双向链表基本操作及代码优化技巧

双向链表基本操作及代码优化技巧以下是本人对双向链表的相关操作及相应的代码优化学习笔记1 双向链表的插入有4种情况:1.1 插入到链表的开始位置1.2 插入到链表的中间位置1.3 插入到链表的结束位置1.4 链表为空,既插入到开始位置同时也插入到结束位置。

1.5 以下是双向链表的示意图:根据分析,写出代码如下:代码1 :[cpp] view plaincopy#include&lt;stdio.h&gt;#include&lt;stdlib.h&gt; typedef struct node{ struct node *prev; struct node *next;int value; }Node; Node*create_node(int value) { Node *root =(Node *)malloc(sizeof(Node)); if (root == NULL)return 0; root-&gt;next = NULL; root-&gt;prev = NULL; root-&gt;value = value; return root; } //此链表有头结点,头结点的prev next 指针分别//指向第一个结点和最后一个结点int list_insert1(Node *root,intvalue) { Node *this; Node *that; Node *new; for (this = root;(that = this-&gt;next)!=NULL; this = that) { if (that-&gt;value ==value){ return 1; } if (that-&gt;value &gt; value){ break; } } //跳出for 循环的条件是找到了待插入的结点//或则是一直没有找到,知道遍历到链表末尾//最后把新节点插入尾端new = create_node(value); //插入到链表开始位置,或则插入在链表中间if (that != NULL) { //插入起始位置if (this ==root){ new-&gt;next = that;root-&gt;next = new; new-&gt;prev = NULL; that-&gt;prev = new; } else{ new-&gt;next = that;this-&gt;next =new; new-&gt;prev = this; that-&gt;prev =new; } } else{ //在链表末尾, that指针为NULL 时跳出for 循环if (this != root){ this-&gt;next = new;new-&gt;next = NULL; new-&gt;prev = this; root-&gt;prev = new; }else { //链表为空root-&gt;next = new; new-&gt;next = NULL; root-&gt;prev = new; new-&gt;prev =NULL; } } return0; }2上面这段代码过于冗长,此处介绍两个优化代码的技巧。

双向链表简介以及使用Java代码实现

双向链表简介以及使用Java代码实现

双向链表简介以及使用Java代码实现一:双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。

所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。

二:使用代码实现public class 双向链表 {public static void main(String[] args) {HeroNode2 name1=new HeroNode2(1,"小袁","世界上最帅的男人");HeroNode2 name2=new HeroNode2(2,"xx","xx");HeroNode2 name3=new HeroNode2(3,"符爱云","我愚蠢的组员");HeroNode2 name4=new HeroNode2(4,"vv","xx");SingleLinkedList2 singleLinkedList=new SingleLinkedList2();singleLinkedList.add(name1);singleLinkedList.add(name4);singleLinkedList.add(name3);singleLinkedList.add(name2);singleLinkedList.list();System.out.println("修改后---------------");HeroNode2 n=new HeroNode2(2,"陆云杰","我愚蠢的组员");singleLinkedList.update(n);singleLinkedList.list();System.out.println("删除后--------------");singleLinkedList.delete(4);singleLinkedList.list();}}class SingleLinkedList2 {//定义头节点,不存放具体数据private HeroNode2 head = new HeroNode2(0, "", "");//返回头节点public HeroNode2 getHead(){return head;}// 添加一个节点到双向链表的最后.public void add(HeroNode2 heroNode) {// 因为head节点不能动,因此我们需要一个辅助遍历 temp HeroNode2 temp = head;// 遍历链表,找到最后while (true) {// 找到链表的最后if (temp.next == null) {//break;}// 如果没有找到最后, 将将temp后移temp = temp.next;}// 当退出while循环时,temp就指向了链表的最后// 形成一个双向链表temp.next = heroNode;heroNode.pre = temp;}//定义修改节点方法public void update(HeroNode2 newHeroNode){if(head.next==null){System.out.println("链表为空");return;}//定义辅助变量HeroNode2 temp=head.next;//定义标志boolean flag=false;while (true) {if (temp == null) {break;}if(temp.SerialNumber==newHeroNode.SerialNumber){ flag=true;break;}temp=temp.next;}if(flag){=;rmation=rmation;}else {System.out.println("没有找到");}}//双向链表可以直接找到,自我删除。

c语言链表代码

c语言链表代码

c语言链表代码以下是一个简单的双向链表的C语言代码:#include<stdio.h>#include<stdlib.h>struct Node {int data;struct Node* prev;struct Node* next;};struct Node* head;创建链表void createList(int n){struct Node* newNode;struct Node* temp;int data, i;head = (struct Node*)malloc(sizeof(struct Node));if (head == NULL) {printf("Memory cannot be allocated.");}else {printf("Enter the data of node 1: ");scanf("%d", &data);head->data = data;head->prev = NULL;head->next = NULL;temp = head;for(i=2; i<=n; i++) {newNode = (struct Node*)malloc(sizeof(struct Node));if (newNode == NULL) {printf("Memory cannot be allocated.");break;}else {printf("Enter the data of node %d: ", i);scanf("%d", &data);newNode->data = data;newNode->prev = temp;newNode->next = NULL;temp->next = newNode;temp = temp->next;}}}}遍历链表void traverseList() {struct Node* temp;if (head == NULL) {printf("List is empty");}else {temp = head;while (temp != NULL) {printf("Data = %d\n", temp->data);temp = temp->next;}}}int main() {int n;printf("Enter the total number of nodes: ");scanf("%d", &n);createList(n);printf("\nData entered in the list:\n");traverseList();return 0;}此代码中的struct Node数据结构包含三个成员变量:- data:节点的数据- prev:指向节点前一个节点的指针- next:指向节点后一个节点的指针在createList函数中,为了方便,我们将第一个节点作为头节点。

c实现双向链表

c实现双向链表

c实现双向链表实现双向链表:创建、插⼊、删除#include <iostream>#include <stdio.h>#include <string.h>#include <stdlib.h>using namespace std;typedef struct student{int data;struct student *next;struct student *pre;}dnode;//创建链表dnode *create(){//1. 定义变量dnode *head = NULL;dnode *p = NULL;dnode *s = NULL;int x = 0;int cycle = 1;//2. 新建headhead = (dnode*)malloc(sizeof(dnode));p = head;//3. 添加节点while(cycle){printf("input the data:");scanf("%d", &x);if (x != 0){s = (dnode*)malloc(sizeof(dnode));s->data = x;p->next = s;s->pre = p;p = s;}else{cycle = 0;}}//4. 删除 headp->next = NULL;p = head;head = head->next;free(p);p = NULL;//5. 返回 headreturn head;}//插⼊节点dnode *insert(dnode *head, int num){//1. 定义变量dnode *p0 = NULL;dnode *p1 = NULL;p1 = head;//2. 新建节点p0 = (dnode*)malloc(sizeof(dnode));p0->data = num;//3. 定位插⼊位置(升序)while(p0->data > p1->data && p1->next != NULL){p1 = p1->next;//4. 插⼊新节点if (p0->data > p1->data) //尾{p1->next = p0;p0->pre = p1;p0->next = NULL;}else{if (head == p1) //头{p0->next = p1;p1->pre = p0;head = p0;}else//中间{p1->pre->next = p0;p0->next = p1;p0->pre = p1->pre;p1->pre = p0;}}//5. 返回 headreturn head;}//删除节点dnode *del(dnode *head, int num){//1. 定义变量dnode *p = NULL;p = head;//2. 定位节点while (num != p->data && p->next != NULL) {p = p->next;}//3. 删除节点if (num != p->data){printf("not found:%d\n", num);}else{if (p == head) //头{head = p->next;head->pre = NULL;free(p);}else if (p->next == NULL) //尾{p->pre->next = NULL;free(p);}else//中间{p->next->pre = p->pre;p->pre->next = p->next;free (p);}}return head;}//计算链表长度int length(dnode *head){dnode *p;int n = 0;p = head;while(p != NULL){p = p->next;n++;printf("len:%d\n", n);return n;}//显⽰void show(dnode *head){dnode *p;int n = 0;p = head;while(p != NULL){printf("data:%d ", p->data); p = p->next;}printf("\n");}int main(){dnode *head = create();show(head);length(head);head = insert(head, 2);show(head);head = del(head, 2);show(head);}。

双向链表的创建,输出,插入数据和删除数据

双向链表的创建,输出,插入数据和删除数据

双向链表的创建,输出,插⼊数据和删除数据#include <stdio.h>#include <stdlib.h>typedef struct aa{int data;struct aa *rlink;struct aa *llink;}DLink;DLink * createLink(DLink *head){//头节点DLink *p,*q;int n;head=p=(DLink *)malloc(sizeof(DLink));head->rlink=NULL;head->llink=NULL;scanf("%d",&n);while(n!=-1){//以输⼊-1作为输⼊数据的结束q=(DLink *)malloc(sizeof(DLink));q->llink=NULL;p->llink=q;q->rlink=p;p=p->llink;p->data=n;scanf("%d",&n);}return head;}void printLink(DLink *p){do{p=p->llink;printf("%d ",p->data);}while(p->llink!=NULL);}DLink * insertdate(DLink *head,int i,int n){int j;DLink *p=head;DLink *q;DLink *s;s=(DLink *)malloc(sizeof(DLink));s->data=n;if(p->llink==NULL){p->llink=s;s->rlink=p;return head;}q=p->llink;for(j=1;j<i&&q!=NULL;j++){p=p->llink;q=p->llink;}if(q==NULL){p->llink=s;s->rlink=q;}else{s->llink=q;q->rlink=s;p->llink=s;s->rlink=p;}return head;}DLink * deleteLink(DLink *head,int j){ int i=1;DLink *p=head,*q=head->llink;while(i<j&&q!=NULL){p=p->llink;q=q->llink;i++;}if(i==j){p->llink=q->llink;q->llink->rlink=p;}return head;}int main(){int i,j,n;//i是要插⼊的序号,n是要插⼊的数据,j是要删除的序号DLink *L;printf("请输⼊双向链表的数据,输⼊-1结束结束输⼊数据:");L=createLink(L);//创建链表printLink(L);//输出链表printf("请输⼊要插⼊的序号和数据(序号要⼤于0):");scanf("%d %d",&i,&n);L=insertdate(L,i,n);//插⼊数据printLink(L);printf("请输⼊请输⼊要删除数据的序号(序号要⼤于0且本序号有对应的数据):"); scanf("%d",&j);L=deleteLink(L,j);//删除链表printLink(L);}。

python-实现双链表

python-实现双链表

python-实现双链表 双链表和单链表进⾏⽐较的优点与不同1. 节点多了⼀个前驱指针域2. 在很多基本操作上,多了⼀种选择,因为双链表可以向前进⾏移动寻位3. 如果给每个节点添加⼀个对应的下标,那么在寻找节点时,我们可以使⽤⼆分发来进⾏节点的寻址⼯作,这相对于单链表是⼀个性能的优化7 """8 python实现双链表9 """10 class Node(object):11 def__init__(self,elem):12 self.elem = elem13 self.next = None14 self.front = None15 class linklist(object):16 def__init__(self,node = None):#链表的初始化17 self.__head = node18 self.curlen = 019 def empty(self):20 if self.head == None:21 raise Exception("链表为空")22 def len(self):23 return self.curlen24 def add_head(self,item):25 node = Node(item)26 node.next = self.__head27 self.__head = node28 self.curlen += 129 def add_tail(self,item):30 node = Node(item)31 tempnode = self.__head32 while tempnode != None:33 tempnode = tempnode.next34 tempnode.next = node35 self.curlen += 136 def insert(self,location,item):37 node = Node(item)38 if location < 0 or location > self.curlen - 1:39 raise Exception("插⼊位置⾮法")40 elif location == 0:41 self.add_head(item)42 elif location == self.curlen:43 tempnode = self.__head44 while tempnode.next != None:45 tempnode = tempnode.next46 tempnode.next = node47 self.curlen += 148 else:49 tempnode = self.__head50 for i in range(location - 1):51 tempnode = tempnode.next52 node.next = tempnode.next53 tempnode.next = node54 self.curlen += 155 def delitem(self,item):56 if self.__head.elem == item:57 self.__head = self.__head.next58 else:59 tempnode = self.__head6061 while tempnode!= None:62 if tempnode.next.elem == item:63 break64 tempnode = tempnode.next65 tempnode.next = tempnode.next.next66 def change(self,item,changed_item):67 tempnode = self.__head68 while tempnode != None:69 if tempnode.elem == item:70 tempnode.elem = changed_item71 break72 def search(self,item):73 tempnode = self.__head74 while tempnode != None:75 if tempnode.elem == item:76 return True77 tempnode = tempnode.next78 return False79 def display(self):80 tempnode = self.__head81 while tempnode != None:82 print(tempnode.elem,end = "")83 tempnode = tempnode.next84 print()85 if__name__ == "__main__":86 linklist1 = linklist()87 linklist1.add_head(1)88 linklist1.add_head(2)89 linklist1.insert(0,3)90 linklist1.display()91 print(linklist1.curlen)92 linklist1.delitem(2)93 linklist1.display()94 linklist1.change(3,4)95 print(linklist1.search(4))96 linklist1.display()此代码并没有充分的利⽤双链表的优点来进⾏操作,有兴趣的同学可以在此基础上来进⾏修改。

ch2-23-双链表存储及运算实现代码

ch2-23-双链表存储及运算实现代码

#include <windows.h>#include "stdio.h"typedef int elementType; //elementType 定义为整数类型//定义方式一typedef struct DLNode{elementType data; //数据元素struct DLNode* prior; //前向指针struct DLNode* next; //后向指针} dnode, *dlinkedList;//定义方式二/*struct DLNode{elementType data;struct DLNode* prior; //前向指针struct DLNode* next;};//typedef struct DLNode dnode, *dlinkedList;typedef LNode dnode, *dlinkedList;*///----------------------------------------------------------------------//1. 双链表初始化--创建只有头结点的空双链表//利用“引用”从子函数向主调函数传递创建的空表void initialList(dnode* & L){L=new dnode; //动态在heap上申请内存,保存节点(头结点)L->prior=L;L->next=L;}/*---------------------------------------------------------------*///2. 求链表的长度--求元素节点的个数,不含头结点//引用返回void listLength1(dnode* L, int & len1){len1=0; //保存长度值dnode *p=L->next; //p指向头结点后面一个节点,即第一个元素节点while(p!=L){len1++; //p!=L说明存在元素节点,计数加1p=p->next; //p的指向后移一个节点}}/*---------------------------------------------------------------*///3. 按序号求元素//用函数返回值返回目标节点的指针,失败返回空指针//用指针参数*p的引用返回目标节点的指针void getElement(dnode *L,int i, dnode* &p1){int j=1;p1=L->next;while((j!=i) && (p1!=L)) //当前节点不是目标节点,又没回到头结点,继续处理下一个节点{p1=p1->next;}}/*---------------------------------------------------------------*///4. 查找元素x 是否在表中,返回目标节点指针和序号//x在表中返回节点指针和序号;x不在表中,返回空指针,序号为0// 目标节点指针和序号,都用引用返回void listLocate(dnode *L, elementType x, dnode* &p, int &j) {p=L->next;j=1;while((p!=L) && (p->data!=x)) //注意循环表的搜索条件{p=p->next;j++;}if (p==L) //如果p为空指针,元素x不在表中,j=0}/*---------------------------------------------------------------*///5. 双链表插入算法bool listInsert(dnode* L, int i, elementType x ){dnode* p=L->next; //p指向第一个数据结点dnode* S;int k=1;while(k!=i && p!=L) //搜索ai节点,p=L即又回到都节点{p=p->next; //p指向下一个节点k++;}if(p==L && k!=i) //当p==L且K==i时,插入位置仍然合法,节点要插在最后return false; //p指向头结点,说明插入位置i不对,返回falseelse{//此时,k=i,p为ai节点的指针//或者p=L,k=i,新节点要插入最后,算法相同S=new dnode; //动态申请内存, 创建一个新节点,即:要插入的节点S->data=x; //装入数据S->prior=p->prior; //s前驱为ai-1S->next=p; //S后继为pp->prior=S; //p的前驱变为SS->prior->next=S; //ai-1的后继为Sreturn true; //正确插入返回true}}/*---------------------------------------------------------------*///6. 双链表的删除算法bool listDelete(dnode* L,int i){dnode* p=L->next; //指向第一个数据结点int k=1;while(k!=i && p!=L) //搜索ai节点,p=L说明又回到头结点{p=p->next;k++;}if(p==L)return false; //删除位置i 超出范围,删除失败,返回falseelse{//此时,p指向aip->next->prior=p->prior; //p的后继ai+1的prior指向p的前驱ai-1p->prior->next=p->next; //p的前驱ai-1的next指向p的后继ai+1delete p; //释放删除节点占据的控件,此句必须,否则这个节点的内存将称为垃圾内存return true; //成功删除,返回true}}/*---------------------------------------------------------------*///7. 尾插法创建带头结点的双链表//用户循环从键盘输入节点元素数据,输入特殊符号结束//新插入的节点位于链表最后//c++ 引用实现--利用引用从本函数向主调函数传递创建的链表void createListR( dnode *& L ){elementType x; //数据元素的数值dnode *p; //L为头节点指针L=new dnode; //产生头节点,动态的在heap上申请内存,存放一个节点(头结点)L->prior=L; //头结点的前、后向指针域皆为LL->next=L;cout<<"请输入元素数据(整数,9999退出):"<<endl;cin>>x;while(x!=9999){p=new dnode; //动态申请内存,产生新节点p->data=x; //写入元素数据p->prior=L->prior; //p前向指针指向原来表尾L->prior->next=p; //原为节点的next指向pL->prior=p; //为节点改为pp->next=L; //为节点p的next指向头结点cin>>x;}p=NULL;}/*---------------------------------------------------------------*///8. 头插法构造带头节点的双链表//用户循环从键盘输入节点元素数据,特殊符号退出//新插入的节点位于头节点之后//使用C++“引用”实现--头插法创建一个带头结点的链表void createListH( dnode *& L ){elementType x; //数据元素的数值dnode *p; //L为头节点指针L=new dnode; //产生头节点,动态的在heap上申请内存,存放一个节点(头结点)L->prior=L; //头结点的前、后向指针域皆为LL->next=L;cout<<"请输入元素数据(整数,9999退出):"<<endl;cin>>x;while(x!=9999){p=new dnode; //动态申请内存,产生新节点p->data=x; //写入元素数据p->next=L->next; //p后向指针指向原来第一个数据节点L->next->prior=p; //原第一数据节点的prior指向pp->prior=L; //p的prior指向LL->next=p; //L的next指向pcin>>x;}p=NULL;}/*---------------------------------------------------------------*///9. 销毁链表//用户在堆上动态申请的内存控件,必须手工释放//否则造成内存泄漏。

Python实现双链表

Python实现双链表

Python实现双链表定义:双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。

所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。

一般我们都构造双向循环链表。

代码:''' 双链表优点: 可以找到前驱和后继,可进可退;缺点: 增加删除节点复杂,需要多分配一个指针存储空间。

适用于需要双向查找节点值的情况'''#创建一个结点类class Node: def __init__(self, value=None): self.value = value self.prev = None self.next = None''' 创建一个双链表'''class doubleLink: def __init__(self): self.header = None # 初始化头结点 self.length = 0 # 链表的长度 # 判断链表是否为空 def is_empty(self): return self.length == 0 ''' 实现向双链表添加元素的功能有三种实现方式: 1.头插法 2.尾插法 3.向双链表的指定位置添加元素 ''' # 1.头插法 def __add__(self, value): node = Node(value) if self.is_empty(): node.prev = self.header self.header = node self.length += 1 return else: node.next = self.header self.header.prev = node self.header = node self.length += 1 # 2.尾插法 def append(self, value): node = Node(value) if self.is_empty(): self.__add__(value) else: cur = self.header while cur.next is not None: cur = cur.next cur.next = node node.prev = cur self.length += 1 # 3.向双链表的指定位置添加元素 def insert(self, index, value): node = Node(value) cur = self.header if index <= 0 or index > self.length: print('您输入的信息有误') return ' ' if index == 1: self.__add__(value) for i in range(2, index): cur = cur.next node.next = cur.next cur.next.prev = node cur.next = node node.prev = cur self.length += 1 return value ''' 实现插寻双链表元素的功能有三种实现方式: 1.根据索引查询元素 2.直接查询元素 3.遍历整个双链表,并打印出所有的元素''' # 1.根据索引查询元素def __getitem__(self, index): cur = self.header for i in range(index - 1): cur = cur.next return cur.value # 2.直接查询元素,并返回该元素的索引 def getIndex(self, value): cur = self.header temp = 0 while cur.next is not self.header: if cur.value == value: return temp + 1 cur = cur.next temp += 1 # 3.遍历整个双链表,并打印出所有的元素 def getAll(self): if self.is_empty(): print('目前双链表中没有元素!') return cur = self.header for i in range(self.length): print('%d' % cur.value, end=' ') cur = cur.next # 4.查询某个元素的后继节点 def getItem(self, value): cur = self.header temp = 0 while cur.next is not self.header: if cur.value == value: if cur.next is not None: return cur.next.value else: return -1 cur = cur.next temp += 1 # 5.查询某个元素的前驱节点def getPrevItem(self, value): cur = self.header temp = 0 while cur.next is not self.header: if cur.value == value: if cur.prev is not None: return cur.prev.value else: return -1 cur = cur.next temp += 1 ''' 实现修改指定位置元素的功能 ''' def __setitem__(self, index, value): cur = self.header for i in range(index - 1): cur = cur.next cur.value = value return value ''' 实现删除双链表元素的功能''' # 直接删除元素def __delete__(self, value): cur = self.header if self.getIndex(value) == 1: self.header = cur.next self.length -= 1 elif self.getIndex(value) != 1: while self.getIndex(value) != self.length: cur = cur.next cur=None self.length -= 1 else: while cur.value != value: cur = cur.next cur.prev.next = cur.next cur.next.prev = cur.prev self.length -= 1if __name__ == '__main__': s = doubleLink() s.__add__(12) s.__add__(13) s.__add__(14) s.__add__(15) s.append(22) s.getAll() print('\n第%d个位置的元素是%d.' % (1, s.__getitem__(1))) print('\n 元素%d在双链表的第%d个位置' % (14, s.getIndex(14))) print('获取元素%d的后继节点%d' % (12, s.getItem(12))) print('获取元素%d的前驱节点%d' % (13, s.getPrevItem(13))) print('在第%d个位置插入元素%d:' % (2, s.insert(2, 45))) s.getAll() print('\n将第%d个位置的元素修改为%d:' % (1, s.__setitem__(1, 900))) s.getAll() print('\n删除元素22:') s.__delete__(22) s.getAll()。

线程安全型双向链表的实现

线程安全型双向链表的实现

线程安全型双向链表的实现线程安全的双向链表实现,使用一个原子锁保护此链表,当需要操作链表时,先获取这个原子锁,移除、添加或者修改链表时,确保线程安全,在操作完成时,释放原子锁:```c// 双向链表class ThreadSafeLinkedList{// 双向链表节点struct Node {int data;struct Node* prev;struct Node* next;};// 原子锁std::atomic<Node*> head;std::atomic<Node*> tail;public:// 构造函数ThreadSafeLinkedList(){// 创建头、尾节点auto h = new Node{0, nullptr, nullptr};auto t = new Node{0, h, nullptr};head.store(h);// h->next = t;tail.store(t);}// 插入节点void insert(int value){auto node = new Node{value, nullptr, nullptr};std::lock_guard<std::mutex> guard(this->lock);// 获取尾节点auto t = tail.load();// 设置尾节点的下一个节点t->next = node;node->prev = t;// 更新尾节点tail.store(node);}// 移除节点void remove(int value){std::lock_guard<std::mutex> guard(this->lock);// 获取头节点auto h = head.load();auto p = h->next;// 遍历链表,查找给定节点while(p != nullptr && p->data != value) {p = p->next;}if(p) {// 移除给定节点p->prev->next = p->next;if(p->next) {p->next->prev = p->prev;} else { //移除的是尾节点tail.store(p->prev);}delete p;}} };```。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

#include <windows.h>#include "stdio.h"typedef int elementType; //elementType 定义为整数类型//定义方式一typedef struct DLNode{elementType data; //数据元素struct DLNode* prior; //前向指针struct DLNode* next; //后向指针} dnode, *dlinkedList;//定义方式二/*struct DLNode{elementType data;struct DLNode* prior; //前向指针struct DLNode* next;};//typedef struct DLNode dnode, *dlinkedList;typedef LNode dnode, *dlinkedList;*///----------------------------------------------------------------------//1. 双链表初始化--创建只有头结点的空双链表//利用“引用”从子函数向主调函数传递创建的空表void initialList(dnode* & L){L=new dnode; //动态在heap上申请内存,保存节点(头结点)L->prior=L;L->next=L;}/*---------------------------------------------------------------*///2. 求链表的长度--求元素节点的个数,不含头结点//引用返回void listLength1(dnode* L, int & len1){len1=0; //保存长度值dnode *p=L->next; //p指向头结点后面一个节点,即第一个元素节点while(p!=L){len1++; //p!=L说明存在元素节点,计数加1p=p->next; //p的指向后移一个节点}}/*---------------------------------------------------------------*///3. 按序号求元素//用函数返回值返回目标节点的指针,失败返回空指针//用指针参数*p的引用返回目标节点的指针void getElement(dnode *L,int i, dnode* &p1){int j=1;p1=L->next;while((j!=i) && (p1!=L)) //当前节点不是目标节点,又没回到头结点,继续处理下一个节点{p1=p1->next;}}/*---------------------------------------------------------------*///4. 查找元素x 是否在表中,返回目标节点指针和序号//x在表中返回节点指针和序号;x不在表中,返回空指针,序号为0// 目标节点指针和序号,都用引用返回void listLocate(dnode *L, elementType x, dnode* &p, int &j) {p=L->next;j=1;while((p!=L) && (p->data!=x)) //注意循环表的搜索条件{p=p->next;j++;}if (p==L) //如果p为空指针,元素x不在表中,j=0}/*---------------------------------------------------------------*///5. 双链表插入算法bool listInsert(dnode* L, int i, elementType x ){dnode* p=L->next; //p指向第一个数据结点dnode* S;int k=1;while(k!=i && p!=L) //搜索ai节点,p=L即又回到都节点{p=p->next; //p指向下一个节点k++;}if(p==L && k!=i) //当p==L且K==i时,插入位置仍然合法,节点要插在最后return false; //p指向头结点,说明插入位置i不对,返回falseelse{//此时,k=i,p为ai节点的指针//或者p=L,k=i,新节点要插入最后,算法相同S=new dnode; //动态申请内存, 创建一个新节点,即:要插入的节点S->data=x; //装入数据S->prior=p->prior; //s前驱为ai-1S->next=p; //S后继为pp->prior=S; //p的前驱变为SS->prior->next=S; //ai-1的后继为Sreturn true; //正确插入返回true}}/*---------------------------------------------------------------*///6. 双链表的删除算法bool listDelete(dnode* L,int i){dnode* p=L->next; //指向第一个数据结点int k=1;while(k!=i && p!=L) //搜索ai节点,p=L说明又回到头结点{p=p->next;k++;}if(p==L)return false; //删除位置i 超出范围,删除失败,返回falseelse{//此时,p指向aip->next->prior=p->prior; //p的后继ai+1的prior指向p的前驱ai-1p->prior->next=p->next; //p的前驱ai-1的next指向p的后继ai+1delete p; //释放删除节点占据的控件,此句必须,否则这个节点的内存将称为垃圾内存return true; //成功删除,返回true}}/*---------------------------------------------------------------*///7. 尾插法创建带头结点的双链表//用户循环从键盘输入节点元素数据,输入特殊符号结束//新插入的节点位于链表最后//c++ 引用实现--利用引用从本函数向主调函数传递创建的链表void createListR( dnode *& L ){elementType x; //数据元素的数值dnode *p; //L为头节点指针L=new dnode; //产生头节点,动态的在heap上申请内存,存放一个节点(头结点)L->prior=L; //头结点的前、后向指针域皆为LL->next=L;cout<<"请输入元素数据(整数,9999退出):"<<endl;cin>>x;while(x!=9999){p=new dnode; //动态申请内存,产生新节点p->data=x; //写入元素数据p->prior=L->prior; //p前向指针指向原来表尾L->prior->next=p; //原为节点的next指向pL->prior=p; //为节点改为pp->next=L; //为节点p的next指向头结点cin>>x;}p=NULL;}/*---------------------------------------------------------------*///8. 头插法构造带头节点的双链表//用户循环从键盘输入节点元素数据,特殊符号退出//新插入的节点位于头节点之后//使用C++“引用”实现--头插法创建一个带头结点的链表void createListH( dnode *& L ){elementType x; //数据元素的数值dnode *p; //L为头节点指针L=new dnode; //产生头节点,动态的在heap上申请内存,存放一个节点(头结点)L->prior=L; //头结点的前、后向指针域皆为LL->next=L;cout<<"请输入元素数据(整数,9999退出):"<<endl;cin>>x;while(x!=9999){p=new dnode; //动态申请内存,产生新节点p->data=x; //写入元素数据p->next=L->next; //p后向指针指向原来第一个数据节点L->next->prior=p; //原第一数据节点的prior指向pp->prior=L; //p的prior指向LL->next=p; //L的next指向pcin>>x;}p=NULL;}/*---------------------------------------------------------------*///9. 销毁链表//用户在堆上动态申请的内存控件,必须手工释放//否则造成内存泄漏。

//用malloc函数申请的内存,用free函数释放//用new操作符申请的内存,用delete操作符释放void destroyList(dnode* & L){dnode *p,*pTemp;L->prior->next=NULL; //将为节点的next置为空,以便删除,其中L->prior为尾节点指针p=L;while(p){pTemp=p->next;delete(p);p=pTemp;}L=NULL;}/*---------------------------------------------------------------*/。

相关文档
最新文档