数据结构中链表及常见操作
数据结构中linklist的理解

数据结构中linklist的理解LinkList(链表)的理解。
在数据结构中,链表(LinkList)是一种基本的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。
链表是一种线性数据结构,它可以用来表示一系列元素的顺序。
与数组不同,链表中的元素在内存中不是连续存储的,而是通过指针相互连接起来的。
这种特性使得链表具有一些独特的优势和应用场景。
链表的基本结构。
链表由节点组成,每个节点包含两部分,数据和指针。
数据部分用来存储元素的值,指针部分用来指向下一个节点。
链表的第一个节点称为头节点,最后一个节点称为尾节点,尾节点的指针指向空值(NULL)。
链表的分类。
链表可以分为单向链表、双向链表和循环链表三种基本类型。
单向链表,每个节点只包含一个指针,指向下一个节点。
双向链表,每个节点包含两个指针,分别指向前一个节点和后一个节点。
循环链表,尾节点的指针指向头节点,形成一个闭环。
不同类型的链表适用于不同的场景,选择合适的链表类型可以提高数据操作的效率。
链表的优势。
链表相对于数组有一些明显的优势:插入和删除操作高效,由于链表中的元素不是连续存储的,插入和删除操作可以在常数时间内完成,而数组中的插入和删除操作需要移动大量元素,时间复杂度为O(n)。
动态扩展,链表的大小可以动态调整,不需要预先分配固定大小的内存空间。
链表的应用场景。
由于链表的优势,它在一些特定的应用场景中得到了广泛的应用:LRU缓存,链表可以用来实现LRU(Least Recently Used)缓存淘汰算法,当缓存空间不足时,链表可以高效地删除最久未使用的元素。
大整数运算,链表可以用来表示大整数,实现大整数的加减乘除运算。
图论算法,在图论算法中,链表常常用来表示图的邻接表,用于表示图中的顶点和边的关系。
链表的实现。
链表的实现可以使用指针或者引用来表示节点之间的关系。
在C语言中,可以使用指针来表示节点之间的连接关系;在Java等语言中,可以使用引用来表示节点之间的连接关系。
常见的数据结构模型

常见的数据结构模型数据结构是计算机科学中重要的基础知识,用于组织和存储数据以便有效地操作和访问。
常见的数据结构模型包括线性结构、树状结构、图状结构和哈希结构。
1.线性结构:线性结构是最简单、最常见的数据结构模型之一,它是一组数据元素按照特定次序排列而成的数据结构。
其中最基本的线性结构是数组和链表。
-数组:数组是一种连续存储的线性结构,所有元素在内存中占用一段连续的地址空间,通过索引值可以快速访问元素。
数组的大小固定,并且插入、删除元素较为复杂。
-链表:链表由节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。
链表可以分为单向链表、双向链表和循环链表等多种形式。
链表的大小可变,插入、删除元素操作较为简单,但访问元素需要遍历链表。
2.树状结构:树状结构是一种非线性的数据结构,它由节点和边组成,每个节点可以有多个子节点。
树状结构常用来表示层次关系,常见的树状结构包括二叉树、堆、平衡二叉树和B树。
-二叉树:二叉树是一种特殊的树结构,每个节点最多有两个子节点。
二叉树可以分为普通二叉树、满二叉树和完全二叉树等多种形式。
-堆:堆是一种特殊的二叉树,对于任意节点N,N的父节点的值大于等于(或小于等于)N的左右子节点的值。
堆常用于实现优先队列等数据结构。
-平衡二叉树:平衡二叉树是一种特殊的二叉树,它的左右子树的高度差不超过1、平衡二叉树常用于提高查找、插入和删除操作的效率,例如AVL树和红黑树等。
-B树:B树是一种多路树,每个节点可以有多个子节点。
B树常用于存储大量数据的数据库和文件系统等场景,可以有效地减少磁盘I/O次数。
3.图状结构:图状结构是一种由节点和边组成的非线性数据结构,节点之间可以有多个关系。
图状结构常用于表示网络、社交关系等复杂的实际问题。
-有向图:有向图中每条边都有一个方向,表示从一个节点到另一个节点的有向关系。
-无向图:无向图中每条边没有方向,表示节点之间的无向关系。
-加权图:加权图中每条边都有一个权值,表示节点之间的带权关系。
节点删除操作方法

节点删除操作方法节点删除是一种常见的数据结构操作,用于从数据结构中删除一个指定的节点。
节点删除操作的实现方法因不同数据结构而异,下面将就几种常见的数据结构——链表、二叉树和图——来分别说明它们的节点删除操作方法。
首先,链表是一种由节点组成的数据结构,其中每个节点包含数据以及指向下一个节点的指针。
在链表中进行节点删除操作,主要有以下几种情况:1. 删除头节点:如果要删除的是链表的头节点,只需将头指针指向第二个节点即可。
可以通过以下代码实现:c++Node* temp = head;head = head->next;delete temp;2. 删除尾节点:要删除链表的尾节点,需要遍历整个链表,找到尾节点的前一个节点,然后将其指向null。
可以通过以下代码实现:c++Node* cur = head;while (cur->next->next != nullptr)cur = cur->next;delete cur->next;cur->next = nullptr;3. 删除中间节点:要删除链表的中间节点,需要找到待删除节点的前一个节点,然后将其指向待删除节点的下一个节点。
可以通过以下代码实现:c++Node* cur = head;while (cur->next->data != target)cur = cur->next;Node* temp = cur->next;cur->next = temp->next;delete temp;接下来,我们来看二叉树的节点删除操作。
二叉树是一种每个节点最多有两个子节点的树结构。
二叉树的节点删除有以下几种情况:1. 删除叶子节点:如果要删除的节点是叶子节点,只需将其父节点指向null即可。
2. 删除只有左子树或只有右子树的节点:如果要删除的节点只有左子树或只有右子树,只需将其父节点指向其子节点即可。
数据结构-单链表基本操作实现(含全部代码)

数据结构-单链表基本操作实现(含全部代码)今天是单链表的实现,主要实现函数如下:InitList(LinkList &L) 参数:单链表L 功能:初始化时间复杂度 O(1)ListLength(LinkList L) 参数:单链表L 功能:获得单链表长度时间复杂度O(n)ListInsert(LinkList &L,int i,ElemType e) 参数:单链表L,位置i,元素e 功能:位置i后插时间复杂度O(n)[加⼊了查找]若已知指针p指向的后插 O(1)ListDelete(LinkList &L,int i) 参数:单链表L,位置i 功能:删除位置i元素时间复杂度O(n)[加⼊了查找]若已知p指针指向的删除最好是O(1),因为可以与后继结点交换数据域,然后删除后继结点。
最坏是O(n),即从头查找p之前的结点,然后删除p所指结点LocateElem(LinkList L,ElemType e) 参数:单链表L,元素e 功能:查找第⼀个等于e的元素,返回指针时间复杂度O(n)代码:/*Project: single linkeed list (数据结构单链表)Date: 2018/09/14Author: Frank YuInitList(LinkList &L) 参数:单链表L 功能:初始化时间复杂度 O(1)ListLength(LinkList L) 参数:单链表L 功能:获得单链表长度时间复杂度O(n)ListInsert(LinkList &L,int i,ElemType e) 参数:单链表L,位置i,元素e 功能:位置i后插时间复杂度O(n)[加⼊了查找]若已知指针p指向的后插 O(1)ListDelete(LinkList &L,int i) 参数:单链表L,位置i 功能:删除位置i元素时间复杂度O(n)[加⼊了查找]若已知p指针指向的删除最好是O(1),因为可以与后继结点交换数据域,然后删除后继结点。
链式结构的组成

链式结构的组成链式结构是一种常见的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。
在这篇文章中,我将介绍链式结构的组成及其相关概念。
一、链式结构的基本组成链式结构由节点组成,每个节点包含数据和指向下一个节点的指针。
节点的数据可以是任意类型,例如整数、字符、字符串等。
指针则是指向下一个节点的地址。
二、链式结构的特点1. 动态性:链式结构可以根据需要动态地添加或删除节点,而不需要提前分配固定大小的内存空间。
2. 灵活性:由于节点之间通过指针连接,链式结构可以非常灵活地进行插入、删除和修改操作。
3. 空间效率:链式结构不需要预先分配连续的内存空间,因此可以更好地利用内存。
4. 时间效率:链式结构的插入和删除操作时间复杂度为O(1),但查找操作的时间复杂度较高,为O(n)。
三、链式结构的分类链式结构可以根据节点之间的关系进行分类,常见的链式结构包括单链表、双链表和循环链表。
1. 单链表单链表是最简单的链式结构,每个节点只包含一个指向下一个节点的指针。
单链表的最后一个节点指向NULL,表示链表的结束。
2. 双链表双链表在单链表的基础上增加了一个指向前一个节点的指针。
这样,双链表可以从前往后或从后往前遍历。
3. 循环链表循环链表是一种特殊的链表,它的最后一个节点的指针指向第一个节点,形成一个闭环。
循环链表可以从任意节点开始遍历。
四、链式结构的操作链式结构支持一系列常见的操作,包括插入、删除和查找等。
1. 插入操作插入操作可以在链表的任意位置插入一个新节点。
具体步骤包括:找到插入位置的前一个节点,创建新节点,将新节点的指针指向下一个节点,将前一个节点的指针指向新节点。
2. 删除操作删除操作可以删除链表中的一个节点。
具体步骤包括:找到要删除节点的前一个节点,将前一个节点的指针指向要删除节点的下一个节点,释放要删除节点的内存空间。
3. 查找操作查找操作可以在链表中查找指定的节点。
具体步骤包括:从链表的头节点开始,依次遍历链表的每个节点,直到找到目标节点或遍历到链表的末尾。
数据结构单链表实验报告

数据结构单链表实验报告一、实验目的1、深入理解单链表的数据结构及其基本操作。
2、掌握单链表的创建、插入、删除、查找等操作的实现方法。
3、通过实际编程,提高对数据结构和算法的理解和应用能力。
二、实验环境1、操作系统:Windows 102、编程语言:C 语言3、开发工具:Visual Studio 2019三、实验原理单链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据域和指针域。
指针域用于指向下一个节点,从而形成链表的链式结构。
单链表的基本操作包括:1、创建链表:通过动态分配内存创建链表的头节点,并初始化链表为空。
2、插入节点:可以在链表的头部、尾部或指定位置插入新的节点。
3、删除节点:根据给定的条件删除链表中的节点。
4、查找节点:在链表中查找满足特定条件的节点。
四、实验内容(一)单链表的创建```cinclude <stdioh>include <stdlibh>//定义链表节点结构体typedef struct Node {int data;struct Node next;} Node;//创建单链表Node createList(){Node head =(Node)malloc(sizeof(Node));if (head == NULL) {printf("内存分配失败!\n");return NULL;}head>data = 0;head>next = NULL;return head;}int main(){Node list = createList();//后续操作return 0;}```在创建单链表时,首先为头节点分配内存空间。
若内存分配失败,则提示错误信息并返回`NULL`。
成功分配内存后,初始化头节点的数据域和指针域。
(二)单链表的插入操作插入操作分为三种情况:头部插入、尾部插入和指定位置插入。
1、头部插入```cvoid insertAtHead(Node head, int data) {Node newNode =(Node)malloc(sizeof(Node));if (newNode == NULL) {printf("内存分配失败!\n");return;}newNode>data = data;newNode>next = head>next;head>next = newNode;}```头部插入时,创建新节点,将新节点的数据域赋值,并将其指针域指向原头节点的下一个节点,然后更新头节点的指针域指向新节点。
链表排序(冒泡、选择、插入、快排、归并、希尔、堆排序)

链表排序(冒泡、选择、插⼊、快排、归并、希尔、堆排序)这篇⽂章分析⼀下链表的各种排序⽅法。
以下排序算法的正确性都可以在LeetCode的这⼀题检测。
本⽂⽤到的链表结构如下(排序算法都是传⼊链表头指针作为参数,返回排序后的头指针)struct ListNode {int val;ListNode *next;ListNode(int x) : val(x), next(NULL) {}};插⼊排序(算法中是直接交换节点,时间复杂度O(n^2),空间复杂度O(1))class Solution {public:ListNode *insertionSortList(ListNode *head) {// IMPORTANT: Please reset any member data you declared, as// the same Solution instance will be reused for each test case.if(head == NULL || head->next == NULL)return head;ListNode *p = head->next, *pstart = new ListNode(0), *pend = head;pstart->next = head; //为了操作⽅便,添加⼀个头结点while(p != NULL){ListNode *tmp = pstart->next, *pre = pstart;while(tmp != p && p->val >= tmp->val) //找到插⼊位置{tmp = tmp->next; pre = pre->next;}if(tmp == p)pend = p;else{pend->next = p->next;p->next = tmp;pre->next = p;}p = pend->next;}head = pstart->next;delete pstart;return head;}};选择排序(算法中只是交换节点的val值,时间复杂度O(n^2),空间复杂度O(1))class Solution {public:ListNode *selectSortList(ListNode *head) {// IMPORTANT: Please reset any member data you declared, as// the same Solution instance will be reused for each test case.//选择排序if(head == NULL || head->next == NULL)return head;ListNode *pstart = new ListNode(0);pstart->next = head; //为了操作⽅便,添加⼀个头结点ListNode*sortedTail = pstart;//指向已排好序的部分的尾部while(sortedTail->next != NULL){ListNode*minNode = sortedTail->next, *p = sortedTail->next->next;//寻找未排序部分的最⼩节点while(p != NULL){if(p->val < minNode->val)minNode = p;p = p->next;}swap(minNode->val, sortedTail->next->val);sortedTail = sortedTail->next;}head = pstart->next;delete pstart;return head;}};快速排序1(算法只交换节点的val值,平均时间复杂度O(nlogn),不考虑递归栈空间的话空间复杂度是O(1))这⾥的partition我们参考(选取第⼀个元素作为枢纽元的版本,因为链表选择最后⼀元素需要遍历⼀遍),具体可以参考这⾥我们还需要注意的⼀点是数组的partition两个参数分别代表数组的起始位置,两边都是闭区间,这样在排序的主函数中:void quicksort(vector<int>&arr, int low, int high){if(low < high){int middle = mypartition(arr, low, high);quicksort(arr, low, middle-1);quicksort(arr, middle+1, high);}}对左边⼦数组排序时,⼦数组右边界是middle-1,如果链表也按这种两边都是闭区间的话,找到分割后枢纽元middle,找到middle-1还得再次遍历数组,因此链表的partition采⽤前闭后开的区间(这样排序主函数也需要前闭后开区间),这样就可以避免上述问题class Solution {public:ListNode *quickSortList(ListNode *head) {// IMPORTANT: Please reset any member data you declared, as// the same Solution instance will be reused for each test case.//链表快速排序if(head == NULL || head->next == NULL)return head;qsortList(head, NULL);return head;}void qsortList(ListNode*head, ListNode*tail){//链表范围是[low, high)if(head != tail && head->next != tail){ListNode* mid = partitionList(head, tail);qsortList(head, mid);qsortList(mid->next, tail);}}ListNode* partitionList(ListNode*low, ListNode*high){//链表范围是[low, high)int key = low->val;ListNode* loc = low;for(ListNode*i = low->next; i != high; i = i->next)if(i->val < key){loc = loc->next;swap(i->val, loc->val);}swap(loc->val, low->val);return loc;}};快速排序2(算法交换链表节点,平均时间复杂度O(nlogn),不考虑递归栈空间的话空间复杂度是O(1))这⾥的partition,我们选取第⼀个节点作为枢纽元,然后把⼩于枢纽的节点放到⼀个链中,把不⼩于枢纽的及节点放到另⼀个链中,最后把两条链以及枢纽连接成⼀条链。
Python数据结构之链表详解

Python数据结构之链表详解⽬录0.学习⽬标1.线性表的链式存储结构1.1指针相关概念1.2指针结构1.3结点1.4结点类2.单链表的实现2.1单链表的初始化2.2获取单链表长度2.3读取指定位置元素2.4查找指定元素2.5在指定位置插⼊新元素2.6删除指定位置元素2.7其它⼀些有⽤的操作3.单链表应⽤3.1单链表应⽤⽰例3.2利⽤单链表基本操作实现复杂操作0. 学习⽬标在顺序存储⽅式中,根据数据元素的序号就可随机存取表中任何⼀个元素,但同时在插⼊和删除运算需要移动⼤量的元素,造成算法效率较低。
解决此缺陷的⼀个办法是:对线性表采⽤链式存储⽅式。
在链表存储⽅式中,在逻辑上相邻的数据元素在存储空间中不⼀定相邻,数据元素的逻辑次序是通过链表中指针链接实现的。
本节将介绍链式存储结构的特点以及各种基本操作的实现。
通过本节学习,应掌握以下内容:线性表的链式存储及实现⽅法链表基本操作的实现利⽤链表的基本操作实现复杂算法1. 线性表的链式存储结构链式存储结构⽤于存放线性表中的元素的存储单元在内存中可以是连续的,也可以是零散分布的。
由于线性表中各元素间存在着线性关系,为了表⽰元素间的这种线性关系,链式存储结构中不仅要存储线性表中的元素,还要存储表⽰元素之间逻辑关系的信息。
所以⽤链式存储结构表⽰线性表中的⼀个元素时⾄少需要两部分信息,除了存储每⼀个数据元素值以外,还需存储其后继或前驱元素所在内存的地址。
采⽤链式存储结构表⽰的线性表简称链表 (Linked List)。
1.1 指针相关概念在继续进⾏讲解前,我们⾸先来了解指针的相关概念,以便更好的理解链表。
假设我们需要处理⼀个⼤型数据⽂件,这⼀⽂件已经被读取保持在内存中,当我们在函数间传递⽂件时,并不会直接传递整个⽂件,我们需要创建变量来保存⽂件在内存中的位置,这些变量很⼩,很容易在不同的函数之间传递。
使⽤指针的好处之⼀就是可以⽤⼀个简单的内存地址就可以指向⼀个更⼤的内存地址段。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
链表 1 定义 链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer)。 由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而顺序表相应的时间复杂度分别是O(logn)和O(1)。 使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。 在计算机科学中,链表作为一种基础的数据结构可以用来生成其它类型的数据结构。链表通常由一连串节点组成,每个节点包含任意的实例数据(data fields)和一或两个用来指向明上一个或下一个节点的位置的链接("links")。 链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的访问往往要在不同的排列顺序中转换。而链表是一种自我指示数据类型,因为它包含指向另一个相同类型的数据的指针(链接)。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。链表有很多种不同的类型:单向链表,双向链表以及循环链表。 2 结构 2.1 单向链表 链表中最简单的一种是单向链表,它包含两个域,一个信息域和一个指针域。这个链接指向列表中的下一个节点,而最后一个节点则指向一个空值。
一个单向链表的节点被分成两个部分。第一个部分保存或者显示关于节点的信息,第二个部分存储下一个节点的地址。单向链表只可向一个方向遍历。 链表最基本的结构是在每个节点保存数据和到下一个节点的地址,在最后一个节点保存一个特殊的结束标记,另外在一个固定的位置保存指向第一个节点的指针,有的时候也会同时储存指向最后一个节点的指针。一般查找一个节点的时候需要从第一个节点开始每次访问下一个节点,一直访问到需要的位置。 2.2 双向链表 每个节点有两个连接:一个指向前一个节点,(当此“连接”为第一个“连接”时,指向空值或者空列表);而另一个指向下一个节点,(当此“连接”为最后一个“连接”时,指向空值或者空列表)
双向链表可以从任何一个节点访问前一个节点,当然也可以访问后一个节点,以至整个链表。一般是在需要大批量的另外储存数据在链表中的位置的时候用。 2.3 循环链表 在一个循环链表中, 首节点和末节点被连接在一起。这种方式在单向和双向链表中皆可实现。要转换一个循环链表,你开始于任意一个节点然后沿着列表的任一方向直到返回开始的节点。指向整个列表的指针可以被称作访问指针。 循环链表中第一个节点之前就是最后一个节点,反之亦然。 3 链表常见用途 常用于组织删除、检索较少,而添加、遍历较多的数据。 4 链表和数组的区别
○1数组在内存中是逐个存放的,也就是说倘若数组的第一个元素在地址A,则数组第二
个元素就在地址A+1。而链表则不是,链表每个节点没有相对固定的位置关系。某个节点在地址A其后的节点不一定是A+1,而在内存的其他空闲区域,呈现一种随机的状态。
○2数组一旦显式的被申明后,其大小就固定了,不能动态进行扩充。而链表则可以,
可以动态生成节点并且添加到已有的链表中。 ○3链表灵活,但是空间和时间额外耗费较大;数组大小固定,元素位置固定,但是操
作不灵活,且容易浪费空间,但是时间耗费较小,尤其是元素变化不大的时候效率很高。双向链表比单向的更灵活,但是空间耗费也更大。
○4从内存存储来看,(静态)数组从栈中分配空间, 对于程序员方便快速,但是自由度小;
链表从堆中分配空间, 自由度大但是申请管理比较麻烦。 附录:(链表的部分常见操作)
1 单向链表 /*线性表的单链表存储结构*/ typedef struct LNode{ ElemType data; struct LNode *next; }LNode, *LinkList;
/*带有头结点的单链表的基本操作(12个)*/ void InitList(LinkList *L) { /* 操作结果:构造一个空的线性表L */ *L=(LinkList)malloc(sizeof(struct LNode)); /* 产生头结点,并
使L指向此头结点 */
if(!*L) /* 存储分配失败*/ exit(OVERFLOW); (*L)->next=NULL; /* 指针域为空 */ }
void DestroyList(LinkList *L) { /* 初始條件:线性表L已存在。操作结果:销毁线性表L */ LinkList q; while(*L) {q=(*L)->next; free(*L); *L=q; } }
void ClearList(LinkList L) /* 不改变L */ { /* 初始条件:线性表L已存在。操作结果:将L重置为空表 */ LinkList p,q; p=L->next; /* p指向第一个结点 */ while(p) /* 没到表尾 */ {q=p->next; free(p); p=q; } L->next=NULL; /* 头结点指针域为空 */ }
Status ListEmpty(LinkList L) { /* 初始条件:线性表L已存在。操作结果:若L为空表,则返回TRUE,否则
返回FALSE */
return L->next == NULL; }
int ListLength(LinkList L) { /* 初始条件:线性表L已存在。操作结果:返回L中数据元素个数 */ int i=0; LinkList p=L->next; /* p指向第一个结点 */ while(p) /* 没到表尾 */ { i++; p=p->next; } return i; }
Status GetElem(LinkList L,int i,ElemType *e) { /* L为带头结点的单链表的头指针。当第i个元素存在时,其值赋给e并返回
OK,否则返回ERROR */ int j=1; /* j为计数器 */ LinkList p=L->next; /* p指向第一个结点 */ while(p&&j < i) /* 顺指针向后查找,直到p指向第i个元素或p为空
*/ { p=p->next; j++; } if(!p||j>i) /* 第i个元素不存在 */ return ERROR; *e=p->data; /* 取第i个元素 */ return OK; }
int LocateElem(LinkList L,ElemType e,Status(*compare)(ElemType,ElemType)) { /* 初始条件: 线性表L已存在,compare()是数据元素判定函数(满足为1,
否则为0) */
/* 操作结果: 返回L中第1个与e满足关系compare()的数据元素的位序。
*/ /* 若这样的数据元素不存在,则返回值为0 */ int i=0; LinkList p=L->next; while(p) { i++; if(compare(p->data,e)) /* 找到这样的数据元素 */ return i; p=p->next; } return 0; }
Status PriorElem(LinkList L,ElemType cur_e,ElemType *pre_e) { /* 初始条件: 线性表L已存在 */
/* 操作结果: 若cur_e是L的数据元素,且不是第一个,则用pre_e返回它
的前驱, */
/* 返回OK;否则操作失败,pre_e无定义,返回INFEASIBLE
*/ LinkList q,p=L->next; /* p指向第一个结点 */ while(p->next) /* p所指结点有后继 */ { q=p->next; /* q为p的后继 */ if(q->data==cur_e) { *pre_e=p->data; return OK; } p=q; /* p向后移 */ } return INFEASIBLE; }
Status NextElem(LinkList L,ElemType cur_e,ElemType *next_e) { /* 初始条件:线性表L已存在 */
/* 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返
回它的后继, */
/* 返回OK;否则操作失败,next_e无定义,返回INFEASIBLE
*/ LinkList p=L->next; /* p指向第一个结点 */ while(p->next) /* p所指结点有后继 */ { if(p->data==cur_e) { *next_e=p->next->data; return OK; } p=p->next; } return INFEASIBLE; }