带头结点单链表中数据就地逆置

合集下载

单链表的逆置(头插法,就地逆转)

单链表的逆置(头插法,就地逆转)

单链表的逆置(头插法,就地逆转)1.头插法,将链表中的每个元素都插到链表头部,进⾏逆转。

void reverse1(Node*head)
{//头插法逆转单链表
Node*p,*q;
p=head->next;
head->next=NULL;
while(p)
{
q=p;
p=p->next;
q->next=head->next;
head->next=q;
}
}
2.就地逆置,将链表中的指针指向改变,最后将head指向链表最后⼀个元素(逆置后的第⼀个)。

void reverse2(Node*head)
{//就地逆转法
Node *p, *s, *t;
p = head; // p开始指向头结点的
s = p->next; // s最开始是指向第⼀个节点的
while ( s->next != null ) // 没有到最后⼀个节点就继续
{
t = s->next; // ⽤t指向s后⾯的⼀个节点
s->next = p; // 把s指向的那个节点想在转换成指向它前⾯的那个节点,这个时候就实现了逆序,⽽且是就地逆序
p = s; // p向后移动到s的位置
s = t; // s向后移动到t的位置,这时候完成了第⼀步的置序,后⾯继续重复之前的动作就OK了
}
head->next = null;
head->next = s;
}。

编写算法:实现带头结点单链表的逆置算法

编写算法:实现带头结点单链表的逆置算法

编写算法:实现带头结点单链表的逆置算法介绍本文将介绍如何编写算法来实现带头结点单链表的逆置操作。

逆置操作是将链表的元素顺序颠倒,即原链表的最后一个节点变为头节点,倒数第二个节点变为第二个节点,以此类推。

实现这个算法需要通过修改指针的指向来完成。

算法实现思路逆置链表的常用方法是使用三个指针prev、current和next: 1. prev指向前一个节点,current指向当前节点,next指向下一个节点。

2. 首先将current节点的下一个节点保存在next指针中,然后将current节点的next指针指向prev节点,实现反转。

3. 接着将prev指针指向current节点,current指针指向next 节点,实现对链表的遍历。

4. 重复上述步骤直到遍历完整个链表,最后将头节点的next指针指向prev节点,完成链表逆置。

伪代码prev = nullcurrent = head.nextwhile(current != null) {next = current.nextcurrent.next = prevprev = currentcurrent = next}head.next = prev算法实现步骤解析初始化1.将prev的初始值设为null,因为头节点的前一个节点不存在。

2.将current的初始值设为头节点的下一个节点,即链表中的第一个节点。

遍历链表1.进入循环,判断current节点是否为null。

如果为null,则表示已经遍历完整个链表。

2.在循环中,首先将current节点的下一个节点保存在next指针中,因为链表逆置的过程中会改变节点的next指向。

3.然后将current节点的next指针指向prev节点,实现反转操作。

4.接着将prev指针指向current节点,即将prev指向已经逆置的部分链表。

5.最后将current指针指向next节点,即将current指向下一个要遍历的节点。

单链表原地逆置(头插法)

单链表原地逆置(头插法)
}
程序执行结果:
p = phead->next->next;//将p指向有效数据的第二个节点,第一个节点不需要插
q = p->next;//q指向p后面的节点,防止后面的节点丢失
phead->next->next = NULL;//把第一个节点的指针域置为空,因为逆置结束后此节点将会是最后一个节点
while(p != NULL)
PNODE reverse_list(PNODE phead);//逆置单链表函数声明
int main(void)
{
PNODE phead;
phead = create_list();
traverse_list(phead);
phead = reverse_list(phead);
traverse_l
PNODE create_list()
{
int val;
PNODE phead,ptail,s;
phead = (PNODE)malloc(sizeof(NODE));
if(phead == NULL)
{
printf("分配失败,程序终止\n");
exit(-1);
}
ptail=phead;
{
PNODE p;
if(phead == NULL)
{
printf("链表为空,请创建链表!\n");
}
else
{
p = phead->next;
printf("依次输出链表的值为:\n");
while(p!=NULL)
{
printf("%d\t",p->data);//依次输出链表的值

c语言单链表头插法实现链表逆置

c语言单链表头插法实现链表逆置

c语言单链表头插法实现链表逆置链表是一种常用的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。

在C语言中,我们可以使用单链表来实现各种操作,如插入、删除和查找等。

本文将介绍如何使用头插法实现链表的逆置。

首先,我们需要定义一个链表节点的结构体,包含数据和指向下一个节点的指针。

代码如下:```ctypedef struct Node {int data;struct Node* next;} Node;```接下来,我们需要实现链表的创建和逆置函数。

首先,创建一个空链表,并将头节点指针指向NULL。

代码如下:```cNode* createList() {Node* head = NULL;return head;}```然后,我们可以实现链表的插入函数,使用头插法将新节点插入到链表的头部。

代码如下:```cNode* insertNode(Node* head, int data) {Node* newNode = (Node*)malloc(sizeof(Node));newNode->data = data;newNode->next = head;head = newNode;return head;}```接下来,我们可以实现链表的逆置函数,通过遍历链表,将每个节点插入到头部,从而实现链表的逆置。

代码如下:```cNode* reverseList(Node* head) {Node* newHead = NULL;Node* temp = NULL;while (head != NULL) {temp = head->next;head->next = newHead;newHead = head;head = temp;}return newHead;}```最后,我们可以编写主函数,测试链表的逆置功能。

代码如下:```cint main() {Node* head = createList();head = insertNode(head, 1);head = insertNode(head, 2);head = insertNode(head, 3);head = insertNode(head, 4);head = insertNode(head, 5);printf("原链表:");Node* temp = head;while (temp != NULL) {printf("%d ", temp->data);temp = temp->next;}printf("\n");head = reverseList(head);printf("逆置后的链表:");temp = head;while (temp != NULL) {printf("%d ", temp->data);temp = temp->next;}printf("\n");return 0;}```运行以上代码,输出结果如下:```原链表:5 4 3 2 1逆置后的链表:1 2 3 4 5```通过以上代码,我们成功地使用C语言的单链表头插法实现了链表的逆置。

数据结构题集答案(C语言版)(严蔚敏_吴伟民著)

数据结构题集答案(C语言版)(严蔚敏_吴伟民著)

第1章 绪论1.1 简述下列术语:数据,数据元素、数据对象、数据结构、存储结构、数据类型和抽象数据类型。

解:数据是对客观事物的符号表示。

在计算机科学中是指所有能输入到计算机中并被计算机程序处理的符号的总称。

数据元素是数据的基本单位,在计算机程序中通常作为一个整体进行考虑和处理。

数据对象是性质相同的数据元素的集合,是数据的一个子集。

数据结构是相互之间存在一种或多种特定关系的数据元素的集合。

存储结构是数据结构在计算机中的表示。

数据类型是一个值的集合和定义在这个值集上的一组操作的总称。

抽象数据类型是指一个数学模型以及定义在该模型上的一组操作。

是对一般数据类型的扩展。

1.2 试描述数据结构和抽象数据类型的概念与程序设计语言中数据类型概念的区别。

解:抽象数据类型包含一般数据类型的概念,但含义比一般数据类型更广、更抽象。

一般数据类型由具体语言系统内部定义,直接提供给编程者定义用户数据,因此称它们为预定义数据类型。

抽象数据类型通常由编程者定义,包括定义它所使用的数据和在这些数据上所进行的操作。

在定义抽象数据类型中的数据部分和操作部分时,要求只定义到数据的逻辑结构和操作说明,不考虑数据的存储结构和操作的具体实现,这样抽象层次更高,更能为其他用户提供良好的使用接口。

1.3 设有数据结构(D,R),其中{}4,3,2,1d d d d D =,{}r R =,()()(){}4,3,3,2,2,1d d d d d d r =试按图论中图的画法惯例画出其逻辑结构图。

解:1.4 试仿照三元组的抽象数据类型分别写出抽象数据类型复数和有理数的定义(有理数是其分子、分母均为自然数且分母不为零的分数)。

解:ADT Complex{ 数据对象:D={r,i|r,i 为实数} 数据关系:R={<r,i>} 基本操作: InitComplex(&C,re,im)操作结果:构造一个复数C ,其实部和虚部分别为re 和imDestroyCmoplex(&C)操作结果:销毁复数CGet(C,k,&e)操作结果:用e返回复数C的第k元的值Put(&C,k,e)操作结果:改变复数C的第k元的值为eIsAscending(C)操作结果:如果复数C的两个元素按升序排列,则返回1,否则返回0IsDescending(C)操作结果:如果复数C的两个元素按降序排列,则返回1,否则返回0Max(C,&e)操作结果:用e返回复数C的两个元素中值较大的一个Min(C,&e)操作结果:用e返回复数C的两个元素中值较小的一个}ADT ComplexADT RationalNumber{数据对象:D={s,m|s,m为自然数,且m不为0}数据关系:R={<s,m>}基本操作:InitRationalNumber(&R,s,m)操作结果:构造一个有理数R,其分子和分母分别为s和m DestroyRationalNumber(&R)操作结果:销毁有理数RGet(R,k,&e)操作结果:用e返回有理数R的第k元的值Put(&R,k,e)操作结果:改变有理数R的第k元的值为eIsAscending(R)操作结果:若有理数R的两个元素按升序排列,则返回1,否则返回0IsDescending(R)操作结果:若有理数R的两个元素按降序排列,则返回1,否则返回0Max(R,&e)操作结果:用e返回有理数R的两个元素中值较大的一个Min(R,&e)操作结果:用e返回有理数R的两个元素中值较小的一个}ADT RationalNumber1.5 试画出与下列程序段等价的框图。

编写算法:实现带头结点单链表的逆置算法

编写算法:实现带头结点单链表的逆置算法

编写算法:实现带头结点单链表的逆置算法标题:探讨带头结点单链表的逆置算法实现及其应用在计算机科学和算法领域,链表是一种非常重要的数据结构,它能够以一种灵活的方式存储和组织数据。

在链表的操作中,逆置算法是一种常见且有用的操作,它能够将链表的顺序颠倒,为问题的解决提供便利。

本文将从简到繁,由浅入深地探讨带头结点单链表的逆置算法的实现及其应用。

1. 带头结点单链表的定义和特点带头结点单链表是一种特殊的链表结构,它在链表的头部增加了一个额外的结点,这个结点并不存储实际的数据,而是作为头结点来方便链表的操作。

带头结点单链表的特点是可以方便地插入和删除操作,同时也更容易处理空链表的情况。

2. 逆置算法的基本思路在带头结点单链表中,逆置算法的基本思路是从链表的第一个结点开始,依次改变每个结点的指针指向,将整个链表的方向颠倒过来。

在实现逆置算法时,需要注意处理好结点指针的指向关系,以免出现指针丢失或者内存泄露的情况。

3. 逆置算法的具体实现(1)需要判断链表是否为空或只有一个结点,如果是的话,则无需进行逆置操作。

(2)使用三个指针分别表示当前结点、前驱结点和后继结点,通过改变指针的指向来逆置链表。

(3)循环迭代链表,直到当前结点为空,完成链表的逆置操作。

4. 逆置算法的应用带头结点单链表的逆置算法在实际应用中有着广泛的使用场景,例如在字符串操作、图论算法、树算法等方面都能够发挥重要作用。

通过逆置算法,可以方便地实现字符串逆置、图的拓扑排序、二叉树镜像等复杂的数据操作。

带头结点单链表的逆置算法是一种非常重要的链表操作,它能够为问题的解决提供便利。

通过对逆置算法的深入理解和应用,可以为算法的设计和问题的解决提供更多的灵感和思路。

希望本文的内容能够帮助读者更深入地理解带头结点单链表的逆置算法,并在实际应用中发挥重要作用。

个人观点:带头结点单链表的逆置算法是一种非常有趣且实用的算法操作,它能够为链表操作和数据处理提供更多的灵活性和便利性。

数据结构课后习题答案详解(C语言版_严蔚敏) 2

数据结构课后习题答案详解(C语言版_严蔚敏) 2

数据结构习题集答案(C语言版严蔚敏)第2章线性表2.1 描述以下三个概念的区别:头指针,头结点,首元结点(第一个元素结点)。

解:头指针是指向链表中第一个结点的指针。

首元结点是指链表中存储第一个数据元素的结点。

头结点是在首元结点之前附设的一个结点,该结点不存储数据元素,其指针域指向首元结点,其作用主要是为了方便对链表的操作。

它可以对空表、非空表以及首元结点的操作进行统一处理。

2.2 填空题。

解:(1) 在顺序表中插入或删除一个元素,需要平均移动表中一半元素,具体移动的元素个数与元素在表中的位置有关。

(2) 顺序表中逻辑上相邻的元素的物理位置必定紧邻。

单链表中逻辑上相邻的元素的物理位置不一定紧邻。

(3) 在单链表中,除了首元结点外,任一结点的存储位置由其前驱结点的链域的值指示。

(4) 在单链表中设置头结点的作用是插入和删除首元结点时不用进行特殊处理。

2.3 在什么情况下用顺序表比链表好?解:当线性表的数据元素在物理位置上是连续存储的时候,用顺序表比用链表好,其特点是可以进行随机存取。

2.4 对以下单链表分别执行下列各程序段,并画出结果示意图。

解:2.5 画出执行下列各行语句后各指针及链表的示意图。

L=(LinkList)malloc(sizeof(LNode)); P=L;for(i=1;i<=4;i++){P->next=(LinkList)malloc(sizeof(LNode));P=P->next; P->data=i*2-1;}P->next=NULL;for(i=4;i>=1;i--) Ins_LinkList(L,i+1,i*2);for(i=1;i<=3;i++) Del_LinkList(L,i);解:2.6 已知L是无表头结点的单链表,且P结点既不是首元结点,也不是尾元结点,试从下列提供的答案中选择合适的语句序列。

a. 在P结点后插入S结点的语句序列是__________________。

单链表就地逆置算法

单链表就地逆置算法

单链表就地逆置算法摘要:1.单链表概述2.单链表就地逆置算法的思路3.单链表就地逆置算法的实现4.单链表就地逆置算法的优点与应用场景正文:一、单链表概述单链表是一种常见的数据结构,它由一系列节点组成,每个节点包含两个部分:数据域和指针域。

数据域用于存储数据,指针域则用于存储下一个节点的地址。

单链表只有一个头节点,但没有尾节点。

在单链表中,我们可以通过遍历指针域来访问整个链表中的数据。

二、单链表就地逆置算法的思路单链表就地逆置算法是一种在原地对单链表进行逆置的操作。

它的主要思路是:从链表的头节点开始,遍历整个链表,同时将当前节点的指针域指向下一个节点,然后将下一个节点的数据域与当前节点的数据域进行交换。

这样,在遍历完整个链表后,链表的头节点将变为尾节点,尾节点将变为头节点,从而实现了链表的逆置。

三、单链表就地逆置算法的实现以下是单链表就地逆置算法的实现过程:1.定义一个指向链表头节点的指针pre,初始时pre 指向头节点。

2.定义一个指向链表尾节点的指针p,初始时p 指向头节点。

3.使用while 循环,当pre 不为空时进行以下操作:a.将p 指向的节点的数据域与pre 指向的节点的数据域进行交换。

b.将pre 指向下一个节点,即pre = pre->next。

c.将p 指向下一个节点,即p = p->next。

4.循环结束后,链表的头节点即为原尾节点,尾节点即为原头节点,实现了链表的逆置。

四、单链表就地逆置算法的优点与应用场景单链表就地逆置算法的优点在于其空间复杂度为O(1),即只需要常数级别的额外空间。

此外,该算法的时间复杂度也为O(n),其中n 为链表的长度。

因此,该算法在处理较长的链表时,依然具有较高的效率。

单链表的就地逆置问题

单链表的就地逆置问题
代码如下:
以上是我对单链表就地逆置的一些理解,希望对各位有所帮助版浏览器
单链表的就地逆置问题
问题描述:编写一个单链表的成员函数,实现对带头结点的单链表的就地逆置操作 涉及变量:position:Node型变量,用于存放尚未反转的结点中首结点的位置
temp:用于标记执行反转操作的结点 涉及教材:《数据结构——Java语言描述(第2版)》 清华大学出版社 大致思路: 将头结点的指针域设为空,再将原来的结点从首结点开始依次连接在头结点之后,即可将原来位置倒置

链表的逆置

链表的逆置

链表的逆置
链表的逆置是一种常见的链表操作,它可以将链表中节点的顺序反转。

逆置链表的基本思路是将链表中的每个节点的指针指向前一个节点。

具体实现时,可以定义三个指针,分别指向当前节点、前一个节点和后一个节点,通过迭代的方式不断地将当前节点的指针指向前一个节点,直到遍历完整个链表。

逆置链表的时间复杂度为O(n),其中n为链表的长度。

逆置链表在很多算法和数据结构中都有应用,例如链表的排序、链表的合并等。

需要注意的是,在逆置链表的过程中需要注意链表头节点的变化,以及空链表和只有一个节点的特殊情况的处理。

- 1 -。

编写算法:实现带头结点单链表的逆置算法

编写算法:实现带头结点单链表的逆置算法

编写算法:实现带头结点单链表的逆置算法引言单链表是一种常见的数据结构,它由一系列节点组成,每个节点包含两部分:数据域和指针域。

其中,数据域用于存储数据,指针域用于指向下一个节点。

在单链表中,头结点是第一个节点之前的一个特殊节点,它不存储任何数据。

逆置(或反转)单链表是将原始链表中的节点顺序颠倒过来。

例如,给定一个单链表:1 -> 2 -> 3 -> 4 -> nullptr,逆置后的结果为:4 -> 3 -> 2 -> 1 -> nullptr。

本文将介绍如何实现带头结点单链表的逆置算法,并给出相应的C++代码实现。

算法思路要实现带头结点单链表的逆置算法,可以使用迭代或递归两种方法。

迭代方法迭代方法通过遍历原始链表中的每个节点,并修改其指针域来实现逆置。

具体步骤如下:1.如果链表为空或只有一个节点,则直接返回。

2.定义三个指针:prev、curr和next。

–prev指向当前节点的前一个节点(初始时为nullptr);–curr指向当前节点;–next指向当前节点的下一个节点。

3.进行循环,直到curr指向nullptr为止:–将curr的指针域修改为prev;–将prev指向curr;–将curr指向next;–将next指向下一个节点。

4.修改头结点的指针域为nullptr,将prev作为新的头结点。

递归方法递归方法通过逐层调用函数来实现逆置。

具体步骤如下:1.如果链表为空或只有一个节点,则直接返回。

2.定义一个递归函数reverseList,该函数接收一个参数:当前节点head。

3.递归终止条件:如果当前节点或当前节点的下一个节点为空,则返回当前节点。

4.在递归调用前,先逆置从下一个节点开始的子链表,并将返回结果保存在变量newHead中。

5.将当前节点的下一个节点的指针域修改为当前节点(即将子链表的尾部连接到当前节点)。

6.将当前节点的指针域修改为空(即将当前节点作为新链表的尾部)。

单链表就地逆置算法

单链表就地逆置算法

单链表就地逆置算法单链表就地逆置算法是一种将单链表逆序排列的算法,不需要创建新的链表,而是通过修改链表的指针来实现逆置操作。

这种算法的时间复杂度为O(n),空间复杂度为O(1)。

在进行单链表就地逆置算法之前,我们需要先了解链表的基本概念和结构。

单链表是由节点组成的数据结构,每个节点包含两个部分:数据域和指针域。

数据域用来存储节点的数据,而指针域用来指向下一个节点。

链表的头节点是链表的第一个节点,尾节点的指针域指向NULL。

现在我们来定义一个单链表的数据结构:```ctypedef struct Node{int data;struct Node *next;```接下来,我们将介绍单链表就地逆置算法的具体实现步骤。

步骤一:检查链表是否为空或只有一个节点,如果是,则不需要进行逆置操作,直接返回头节点。

步骤二:定义三个指针变量,分别为prev、current和next。

```cNode *prev = NULL;Node *current = head;Node *next = NULL;```其中,prev用来指向当前节点的前一个节点,current用来指向当前节点,next用来指向当前节点的下一个节点。

步骤三:遍历链表,将每个节点的指针指向它的前一个节点。

具体操作如下:while(current != NULL){next = current->next;current->next = prev;prev = current;current = next;}```将next指向current节点的下一个节点,然后将current节点的指针指向prev,最后将prev指向current,current指向next。

步骤四:将链表的头节点指向逆置后的链表的头节点。

```chead = prev;```步骤五:返回逆置后的链表头节点。

```creturn head;```下面我们来看一下单链表就地逆置算法的完整代码实现:```cNode *reverseLinkedList(Node *head){if(head == NULL || head->next == NULL){return head;}Node *prev = NULL;Node *current = head;Node *next = NULL;while(current != NULL){next = current->next;current->next = prev;prev = current;current = next;}head = prev;return head;}```通过以上步骤,我们可以实现单链表的就地逆置算法。

数据结构链表的头插法逆置

数据结构链表的头插法逆置

数据结构链表的头插法逆置链表的逆置之头插法:头插法的核⼼思想就是先把当前的链表切分为两个部分,第⼀个部分为只有⼀个头节点的单链表,第⼆个部分是除头节点外的剩余所有的链表,挨个把第⼆部分的节点插⼊到第⼀个部分中,插⼊的⽅法是运⽤建⽴单链表的头插法,其刚好可以起到逆置的作⽤。

此⽅法的空间复杂度为O(1)代码如下:void reverse(LinkList *L){LinkList *p=L->next,*q;//p指向的是L的⾸节点L->next=NULL;//重新设定L是⼀个带头节点的空表while(p!=NULL){q=p->next;//设定q为p的后继节点q->next=L->next;//头插法将q插⼊到L的后⾯L->next=q;//头插法p=q;//q后移,继续头插法直到p为空}}完整的测试代码:#include<stdio.h>#include<stdlib.h>typedef struct node{int data;struct node *next;}Node;void creat_linkList(Node *L){//尾插法Node *rear=L;for(int i=0;i<10;i++){Node *node=(Node *)malloc(sizeof(Node));node->data=i;node->next=NULL;rear->next=node;rear=node;}}void reverse(Node *L){Node *p=L->next;L->next=NULL;Node *q=NULL;while(p!=NULL){q=p->next;//定义⼀个在p后⾯的节点为qp->next=L->next;//L的next指的是p原先的位置,现在需要p回头指向⾃⼰原先指定的位置L->next=p;//再让L的next记录当前p的位置,⽅便p往后移后,新的p可以回头指⾃⼰先前的位置达到逆转的作⽤p=q;//p再转到下⼀个位置}}int main(){Node L;L.data=1000;L.next=NULL;creat_linkList(&L);reverse(&L);Node *p=L.next;while(p!=NULL){printf("%d\n",p->data);p=p->next;}}。

实现单链表的就地逆置算法

实现单链表的就地逆置算法

实现单链表的就地逆置算法题目:有一个线性表(a1,a2,a3,....,an),采用带头节点的单链表L存储,设计一个算法将其就地逆置。

所谓“就地”指辅助空间应该为O(1)。

方法一:采用头插法先将L的头节点head的Next域置为NULL变成一个空链表,然后用p结点采用头插法插入到L中。

[java] view plaincopy1.static Node headInsert(Node head){2.if(head == null || head.next == null){3.System.out.println("逆置的单链表至少有2个结点");4.return null;5.}6.else{7.Node p = head.next;8.head.next = null;9.Node q = null;10.while(p != null){11.q = p;12.p = p.next;13.q.next = head;14.head = q;15.}16.return q;17.}18.}方法二:先将首节点的next置为NULL,用p,q指向单链表中相邻的两节点,将r指向q的下一个结点,然后同步后移。

当q=NULL时,表示指向原单链表的尾结点,将L的next域指向p即可。

[java] view plaincopy1.static Node invert(Node head){2.Node p,q,r;3.if(head == null || head.next == null){4.System.out.println("逆置的单链表至少有2个结点");5.return null;6.}7.else{8.p = head;9.q = p.next;10.while(q != null){11.r = q.next;12.q.next = p;13.p = q;14.q = r;15.}16.head.next = null;17.head = p;18.return head;19.}20.}[java] view plaincopy。

数据结构学习-带头结点的单链表就地逆置

数据结构学习-带头结点的单链表就地逆置

数据结构学习-带头结点的单链表就地逆置所谓“就地是指辅助空间复杂度为O(1)。

解法⼀:将头结点摘下,然后从第⼀结点开始,依次前插⼊到头结点的后⾯(头插法),直到最后⼀个结点为⽌。

代码如下解法⼆:通过若⼲操作将指针反转达到逆置的⽬的。

假设pre、p和r指向3个相邻的结点,如上图。

*pre之前的结点的指针都已经调整完毕,它们的next指针都指向其原前驱结点。

现在令*p结点的next域指向*pre结点,注意到⼀旦调整指针的指向后,*p的后继结点的链就断开了,为此⽤r来指向原*p结点的后继结点。

处理第⼀个结点时,将其next域置为NULL,。

处理最后⼀个结点后,将头结点的指针指向它。

代码:LinkList Reverse (LinkList L){ LNode *p,*r;//p 为⼯作指针,r 为p 的后继以防断链 p=L->next;//从第⼀个元素结点开始 L->next=NULL;//先将头结点L 的next 域置为NULL while (p!=NULL)//依次将元素结点摘下 { r =p->next;//暂存p 的后继 p->next=L->next;//将p 结点插⼊到头结点之后 L->next=p; p =r; } return L;}Linklist reserve(LinkList L){ LNode *pre,*p=L->next,*r=p->next; p ->next=NULL;//处理第⼀个结点 while (r!=NULL)//r 为空,则说明p 为最后⼀个结点 { pre =p;//依次遍历 p=r; r =r->next; p ->next=pre;//指针反转 } L->next=p;//处理最后⼀个结点 return L;}。

算法总结之将单链表的每K个节点之间逆序

算法总结之将单链表的每K个节点之间逆序

算法总结之将单链表的每K个节点之间逆序给定⼀个单链表的表头节点head,实现⼀个调整单链表的函数,是的每k个节点之间逆序,如果最后不够k个节点⼀组,则不调整最后⼏个节点思路:如果k的值⼩于2,不调整。

k<1 没有意义,k==1代表1个节点为1组进⾏逆序,原链表不变。

介绍两种⽅法:⽅法⼀利⽤栈结构1、从左到右便利链表,如果栈的⼤⼩不等于k,就将节点不断压⼊栈中2、当栈⼤⼩第⼀次到达k,凑齐了k个节点进⾏逆序。

然后弹出,并且连接。

第⼀组逆序完成后,记录新的头,同时第⼀组最后⼀个(原头)连接下⼀个节点package TT;import java.util.Stack;public class Test103 {public class Node{public int value;public Node next;public Node(int data){this.value = data;}}public Node reverseKNodes1(Node head, int k){if(k<2){return head;}Stack<Node> stack = new Stack<Node>();Node newHead = head;Node cur = head;Node pre = null;Node next = null;while(cur!=null){next = cur.next;stack.push(cur);if(stack.size()==k){pre=resign1(stack, pre, next);newHead = newHead==head ? cur : newHead;}cur = next;}return newHead;}public Node resign1(Stack<Node> stack, Node left, Node right){Node cur = stack.pop();if(left !=null){left.next=cur;}Node next=null;while(!stack.isEmpty()){next = stack.pop();cur.next=next;cur=next;}cur.next=right;return cur;}} ⽅法⼆、不需要栈结构,在原链表中直接调整⽤变量记录每⼀组开始的第⼀个节点和最后⼀个节点。

数据结构课后习题答案第二章 线性表

数据结构课后习题答案第二章   线性表

第二章线性表2.1描述以下三个概念的区别:头指针,头结点,首元结点(第一个元素结点)。

并说明头指针和头结点的作用。

答:头指针是一个指针变量,里面存放的是链表中首结点的地址,并以此来标识一个链表。

如链表H,链表L等,表示链表中第一个结点的地址存放在H、L中。

头结点是附加在第一个元素结点之前的一个结点,头指针指向头结点。

当该链表表示一个非空的线性表时,头结点的指针域指向第一个元素结点,为空表时,该指针域为空。

开始结点指第一个元素结点。

头指针的作用是用来惟一标识一个单链表。

头结点的作用有两个:一是使得对空表和非空表的处理得以统一。

二是使得在链表的第一个位置上的操作和在其他位置上的操作一致,无需特殊处理。

2.2填空题1、在顺序表中插入或删除一个元素,需要平均移动(表中一半)元素,具体移动的元素个数与(表长和该元素在表中的位置)有关。

2、顺序表中逻辑上相邻的元素的物理位置(必定)相邻。

单链表中逻辑上相邻的元素的物理位置(不一定)相邻。

3、在单链表中,除了首元结点外,任一结点的存储位置由(其直接前驱结点的链域的值)指示。

4、在单链表中设置头结点的作用是(插入和删除元素不必进行特殊处理)。

2.3何时选用顺序表、何时选用链表作为线性表的存储结构为宜?答:在实际应用中,应根据具体问题的要求和性质来选择顺序表或链表作为线性表的存储结构,通常有以下几方面的考虑:1.基于空间的考虑。

当要求存储的线性表长度变化不大,易于事先确定其大小时,为了节约存储空间,宜采用顺序表;反之,当线性表长度变化大,难以估计其存储规模时,采用动态链表作为存储结构为好。

2.基于时间的考虑。

若线性表的操作主要是进行查找,很少做插入和删除操作时,采用顺序表做存储结构为宜;反之,若需要对线性表进行频繁地插入或删除等的操作时,宜采用链表做存储结构。

并且,若链表的插入和删除主要发生在表的首尾两端,则采用尾指针表示的单循环链表为宜。

2.10 Status DeleteK(SqList &a,int i,int k)//删除线性表a中第i个元素起的k个元素{if(i<1||k<0||i+k-1>a.length) return INFEASIBLE;for(count=1;i+count-1<=a.length-k;count++) //注意循环结束的条件a.elem[i+count-1]=a.elem[i+count+k-1];a.length-=k;return OK;}//DeleteK2.11设顺序表中的数据元素递增有序,试写一算法,将X插入到顺序表的适当位置上,以保持该表的有序性。

头插法将单链表原地逆转

头插法将单链表原地逆转

头插法将单链表原地逆转
如果你看到标题就知道我在说什么,那么出门左拐,⾃⼰动⼿写⼀下伪代码。

只有⾃⼰亲⼿写出和画出,才能更好的掌握。

现在有⼀个链表,Head指向头
然后使⽤temp保存Head中原来含有的结点的第⼀个结点,此时p指向第⼀个待插⼊结点
此时将head尾部置空
将 p 加⼊head头部,然后 p 后移⼀位。

往复多次,直到 p 空
1def reverse(self): #头插法原地逆转链表
2 p = self.head #p指向⼯作结点
3 self.head = None #将头指针看做⼀个空空的⼲净的头指针
4while p:
5 temp = self.head #保存头指针已经保存了的后续结点的第⼀个结点
6 self.head = p #将新结点头插法接到头指针上之后的步骤不能反过来哦,否则结果不是预期的结果
7 p = p.Next # STEP 1 :先将⼯作指针 p 后移到下⼀位
8 self.head.Next = temp # STEP 2 :然后再把原来的 head 的后⾯的结点 temp 连接到新加⼊的结点后⾯
9#注:STEP 1 和STEP 2 务必不要颠倒因为如果先执⾏ self.head.Next = temp 那么 p 的next就会变成 temp 是吧(你品品)。

把一个带头结点的单链表所有数据结点逆置

把一个带头结点的单链表所有数据结点逆置
q=q->next;
while(p->next!=s)
{
p=p->next;
}
s=p;
p=q;
}
}
void main()
{
LinkList *L;
Initial(L);
Input(L);
DisplayLink(L);
oppverse(L);
cout<<"逆置后的单链表为:"<<endl;
DisplayLink(L);
}
{
L=new LinkList;
L->next=NULL;
}
void LinkInsert(LinkList *&L,ElemType e) //插入结点
{
LinkList *p=L;
while(p->next!=NULL)
{
p=p->next;
}
LinkList *s;Hale Waihona Puke s=new LinkList;
{
LinkList *p=L,*q,*s;
while(p->next!=NULL)
{
s=p->next;
p=p->next;
}
p=L;
q=L->next;
ElemType temp;
while(p->next!=s)
{
temp=s->data;
s->data=q->data;
q->data=temp;
}
}
void DisplayLink(LinkList *&L)
{
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
编写算法实现带头结点单链表的就地逆置,即利用原带头结点单链表的结点空间把数据元素序列逆置。
四、实验程序:
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
typedef int datatype;
typedef struct snode
{
datatype data;
return 0;
}
if((q=(slnode*)malloc(sizeof(slnode)))==NULL)exit(1);
q->data=x;
q->next=p->next;p->next=q;
return 1;
}
int slldelete(slnode*head,int i,datatype x)
return 0;
}
*x=p->data;
return 1;
}
int sllnotempty(slnode*head)
{
if(head->next==NULL)return 0;
else return 1;
}
linlistsort(slnode*head)
{
slnode*curr,*pre,*p,*q;
main(void)
{
datatype test[6]={64,6,7,89,12,24};
slnode*head,*p;
int n=6,i;
sllinitiate(&head);
for(i=1;i<=n;i++)
sllinsert(head,i,test[i-1]);
linlistsort(head);
struct snode*next;
}slnode;
sllinitiate(slnode**head);
linlistsort(slnode*head);
int sllinsert(slnode*head,int i,datatype x);
int slldelete(slnode*head,int i,datatype x);
(*head)->next=NULL;
}
int sllinsert(slnode*head,int i,datatype x)
{
slnode*p,*q;
int j;
p=head;j=0;
while(p!=NULL&&j<i-1)
{
p=p->next;j++;
}
if(j!=i-1)
{
printf("the insert-position parameter is wrong!\n");
p=head->next;
head->next=NULL;
while(p!=NULL)
{
curr=head->next;
pre=head;
while(curr!=NULL&&curr->data<=p->data)
{
pre=curr;
curr=curr->next;
}
q=p;
p=p->next;
q->next=pre->next;
{
slnode*p,*q;
int j;
p=head;j=0;
while(p->next!=NULL&&j<i-1)
{
p=p->next;j++;
}
if(j!=i-1)
{
printf("the delete-position parameter is wrong!\n");
return 0;
}
q=p->next;p->next=p->next->next;
x=q->data;
free(q);
return 1;
}
int sllget(slnode*head,int i,datatype*x)
{
slnode*p;
int j;
p=head;j=0;
while(p->next!=NULL&&j<i)
{
p=p->next;j++;
}
if(j!=i)
{
printf("the get-position parameter is wrong!\n");
while(p!=NULL)
{
q=p;
p=p->next;
q->next=head->next;
head->next=q;
}
}
实验3:带头结点单链表中数据就地逆置
一、实验目的:
1.会定义单链表的结点类型;
2.熟悉对单链表的一些基本操作和具体的函数定义;
3.了解和掌握单链表的调用格式。
二、实验要求:
1.认真阅读和掌握实验内容所给的程序,并上机运行;
2.保存程序运行结果,并结合程序进行分析;
3.尝试自己调试修改程序并试运行。
三、实验内容:
}
if((q=(slnode*)malloc(sizeof(slnode)))==NULL)exit(1);
q->data=x;
q->next=pre->next;
pre->next=q;
}
converse(slnode*head)
{
slnode*p,*q;
p=head->next;
head->next=NULL;
int sllget(slnode*head,int i,datatype*x);
int sllnotempty(slnode*head);
linlistsurt(slnode*head);
linlistinsert(slnode*head,datatype x);
converse(slnode*head);
linlistinsert(head,25);
converse(head);
p=head->next;
whiltf("%d",p->data);
p=p->next;
}
}
sllinitiate(slnode**head)
{
if((*head=(slnode*)malloc(sizeof(slnode)))==NULL)exit(1);
pre->next=q;
}
}
linlistinsert(slnode*head,datatype x)
{
slnode*curr,*pre,*q;
curr=head->next;
pre=head;
while(curr!=NULL&&curr->data<=x)
{
pre=curr;
curr=curr->next;
相关文档
最新文档