单链表就地逆置算法C语言版

合集下载

单链表逆置算法详解

单链表逆置算法详解
int num; struct List *next; }LNode,LinkList;
/*****************************************
*Funtion: LNode*Creation(int n)
*Descrition: create a singly linked list according to the specified length
*Data:2014-02-28 ******************************/
LinkList Reverse(LNode *head)
{
LNode *p;
//定义中间转换节点
LNode *r;
if(head->next && head->next->next)
{
p=head; //获取头节点地址
printf(“%d ”,p2->num); p2=p2->num; } return 0; }
*Param: n indicate the length you want to create.
*Data:2014-02-28
*****************************************/
LNode *Creation(int n)
{
LinkList head; //定义一个头节点
r=p->next; //获取链表第二个节点地址
p->next=NULL; //头节点变尾节点之后下个指向是 NULL
while(r)
{
p=r; //第一个节点顺移
r=r->next;
//第二个节点顺移

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

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

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

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

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

算法实现思路逆置链表的常用方法是使用三个指针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指向下一个要遍历的节点。

c语言编程acm链表的逆置

c语言编程acm链表的逆置

标题:C语言编程ACM:链表的逆置一、概述ACM(Advanced Computing Machinery)竞赛是计算机科学领域最负盛名的竞赛之一,要在ACM竞赛中获得优异的成绩,熟练掌握C 语言编程技术是必不可少的。

本文将讨论C语言编程中常见的ACM题目之一:链表的逆置。

二、链表的基本概念1.链表的定义链表是一种线性表的物理存储单位,由一个个节点组成,每个节点包含数据元素和下一个节点的指针。

链表中的数据元素可以是任意类型。

2.链表的基本操作在C语言中,链表的基本操作包括插入节点、删除节点、查找节点等。

而链表的逆置就是将链表中的节点顺序颠倒。

三、链表的逆置方法在C语言中,链表的逆置可以采用多种方法实现。

1.迭代法迭代法是最直接的方法,具体步骤如下:(1)初始化三个指针,分别指向当前节点、前一节点、后一节点。

(2)遍历链表,将当前节点的指针指向前一节点。

(3)更新前一节点和当前节点的位置。

(4)遍历结束后,前一节点指向NULL,表示逆置完成。

2.递归法递归法是一种更为巧妙的方法,具体步骤如下:(1)递归遍历链表,直至到达链表尾部。

(2)从链表尾部开始,逐一修改每个节点的指针指向。

(3)递归结束后,链表即被逆置。

四、链表逆置的C语言实现以下是链表逆置的C语言实现代码,以迭代法为例:```ctypedef struct Node {int data;struct Node* next;} Node;Node* reverseList(Node* head) {Node *prev = NULL, *curr = head, *next = NULL; while (curr) {next = curr->next;curr->next = prev;prev = curr;curr = next;}return prev;}```五、实例分析假设有一个链表的头指针为head,包含数据元素1、2、3、4、5。

数据结构课后习题答案详解(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结点的语句序列是__________________。

单链表的就地逆置问题

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

单链表的逆置的实现

单链表的逆置的实现
| (2) |(1)
| t
| (3) |(4)
r y
第三个循环(并对上面的进行整理)
---------------------------------------------
(1) t = y->next
b ---> a ---> NULL c ---> d --> NULL
| | |(1)
r y t
r y t
---------------------------------------------
(2) y->next = r
b ---> a ---> NULL c ---> d --> NULL
| (2) | |(1)
y r t
---------------------------------------------
|(0) (2) | (1)
| t
|(3) | (4)
r y
第二次while循环(并对上面进行整理)
---------------------------------------------
(1) t = y->next
a ---> NULL b ---> c ---> d --> NULL
| | |(1)
单链表的逆置的实现:
(1)算法
struct link
{
int data;
struct link *next;
};
link reverse(link x)
{
if( NULL==x )
return NULL;
link t=NULL;
link r=NULL, y=x; //(0)

链表逆置算法

链表逆置算法

链表逆置算法链表是一种常用的数据结构,它由一系列的节点组成,每个节点包含一个数据元素和一个指针,用于指向下一个节点。

在实际应用中,经常需要将链表进行逆置操作,即将链表中的元素反序排列。

本文将介绍链表逆置算法的实现原理和具体步骤。

链表逆置算法的实现原理是通过改变节点之间的指针指向关系,将原来的链表转换为一个逆序的链表。

具体步骤如下:1. 定义三个指针:prev、cur和next。

其中prev用于指向当前节点的前一个节点,cur用于指向当前节点,next用于保存当前节点的下一个节点。

2. 将cur指针指向链表的头节点。

3. 在循环中,依次对cur指针指向的节点进行操作,直到cur指向链表的最后一个节点。

循环条件可设为cur不为空。

4. 在循环中,将next指针指向cur的下一个节点。

5. 将cur的指针指向prev,实现节点指针的反向。

6. 将prev指针指向cur,cur指针指向next。

7. 遍历完所有节点后,将链表的头节点指向prev,即可得到逆序的链表。

下面通过一个具体例子来说明链表逆置算法的实现过程:假设有一个链表,包含5个节点,数据分别为1、2、3、4、5。

初始状态下,链表的指针指向关系如下:1 ->2 ->3 ->4 -> 5按照上述步骤进行逆置操作:1. 初始化prev、cur和next指针。

2. cur指向链表的头节点,即1。

3. 在循环中,将next指向cur的下一个节点,即2。

4. 将cur的指针指向prev,实现节点指针的反向,此时第一个节点指向null。

5. 将prev指向cur,cur指向next。

6. 继续循环,next指向cur的下一个节点,即3。

7. 将cur的指针指向prev,实现节点指针的反向,此时第二个节点指向第一个节点。

8. 将prev指向cur,cur指向next。

9. 继续循环,重复上述步骤,直到遍历完所有节点。

最终得到的逆序链表的指针指向关系如下:5 -> 4 -> 3 -> 2 -> 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.将当前节点的指针域修改为空(即将当前节点作为新链表的尾部)。

逆置单链表(基于c语言)

逆置单链表(基于c语言)

逆置单链表(基于c语⾔)直接插⼊全部代码:(reverseLinklist函数是逆置操作)#include <stdio.h>#include <stdlib.h>#include <assert.h>typedef int LDataType;typedef struct Linklist{LDataType data;struct Linklist *next;}Linklist,*pLinklist;pLinklist BuyNewNode(LDataType data); //动态⽣成新结点void InitLinklist(pLinklist *pL); //初始化单链表void PushBackLinklist(pLinklist *pL,LDataType data); //尾插void PushFrontLinklist(pLinklist *pL,LDataType data); //头插void PopBackLinklist(pLinklist* pL); //尾删void PopFrontLinklist(pLinklist *pL); //头删void PrintLinklist(Linklist *pL); //打印单链表pLinklist FindLinklist(pLinklist *pL,LDataType data); //查找指定元素,返回元素位置void InsertLinklist(pLinklist *pL,pLinklist p,LDataType data); //指定位置插⼊void RemoveLinklist(pLinklist* pL,LDataType data); //删除第⼀个指定元素void RemoveAllLinklist(pLinklist *pL,LDataType data); //删除所有指定元素int IsEmptyLinklist(pLinklist pL); //判断链表是否为空void DestoryLinklist(pLinklist *pL); //销毁单链表pLinklist reverseLinklist(pLinklist *pL);int main(void){Linklist *first = NULL;InitLinklist(&first);PushBackLinklist(&first,5);PushBackLinklist(&first,4);PushBackLinklist(&first,3);PushBackLinklist(&first,2);PushBackLinklist(&first,1);PushBackLinklist(&first,0);PushFrontLinklist(&first,6);first = reverseLinklist(&first);PushFrontLinklist(&first,-1);PrintLinklist(first);}pLinklist BuyNewNode(LDataType data){pLinklist NewNode = (pLinklist)malloc(sizeof(Linklist));if (NewNode == NULL){printf("动态开辟内存空间失败\n");return NULL;}NewNode->data = data;NewNode->next = NULL;return NewNode;}void InitLinklist(pLinklist *pL){assert(pL != NULL); //初始化操作(*pL) = NULL;}void PushBackLinklist(pLinklist *pL,LDataType data){assert(pL != NULL); //尾插⼀个数据域为data的结点pLinklist NewNode = BuyNewNode(data);if(*pL == NULL){*pL = NewNode;return ;}pLinklist cur = *pL;while(cur->next){cur = cur->next;}cur->next = NewNode;}void PushFrontLinklist(pLinklist *pL,LDataType data){assert(pL != NULL); //头插⼀个数据域为data的结点pLinklist NewNode = BuyNewNode(data);if(*pL == NULL){*pL = NewNode;return ;}NewNode->next = *pL;*pL = NewNode;}int IsEmptyLinklist(pLinklist pL){return (pL == NULL); //判断⽆头单链表是否为空}void PopBackLinklist(pLinklist *pL){assert(pL != NULL); //尾删if(IsEmptyLinklist(*pL)){puts("链表为空,删除失败");return ;}pLinklist cur = *pL;pLinklist pre;if(cur->next == NULL){//只有⼀个结点*pL = NULL;free(cur);cur = NULL;return ;}while(cur->next){pre = cur;cur = cur->next;}pre->next = NULL;free(cur);cur = NULL;}void PopFrontLinklist(pLinklist *pL){assert(pL != NULL); //头删,既是删除第⼀个结点if(*pL == NULL){printf(" 链表为空,删除失败");return ;}pLinklist cur = *pL;*pL = cur->next;free(cur);cur = NULL;}pLinklist FindLinklist(pLinklist *pL,LDataType data){assert( pL != NULL); //找到第⼀个数据为data的结点pLinklist cur = *pL;while(cur){if (cur->data == data){return cur;}cur = cur->next;}return NULL;}void InsertLinklist(pLinklist *pL,pLinklist p,LDataType data){assert(pL != NULL); //xiangp结点之前插⼊⼀个数据为data的元素 pLinklist NewNode = BuyNewNode(data);pLinklist cur = *pL;while(cur->next != p){cur = cur->next;}NewNode->next = p;cur->next = NewNode;}void RemoveLinklist(pLinklist *pL,LDataType data){assert(pL != NULL); //删除第⼀个数据域为data的结点pLinklist cur = NULL;pLinklist p = *pL;pLinklist pre = NULL;cur = FindLinklist(pL,data);if (cur == NULL){printf("未找到要删除的元素");return ;}if (*pL == cur){//位于第⼀个结点*pL = cur->next;free(cur);cur = NULL;return ;}while(p != cur){pre = p;p = p->next;}pre->next = cur->next;free(cur);cur = NULL;}void RemoveAllLinklist(pLinklist *pL,LDataType data){assert(pL != NULL); //删除每⼀个数据域都是data的结点pLinklist cur = NULL;pLinklist p = *pL;pLinklist pre = *pL;while(p){if (p->data == data && (*pL) == p){//第⼀个结点是pre = p;p = p->next;*pL = p;free(pre);pre = NULL;}else if(p->data == data){//后续结点是cur = p;p = p->next;pre->next = p;free(cur);cur = NULL;}else{//此结点不是pre = p;p = p->next;}}}void PrintLinklist(Linklist *pL){pLinklist cur = pL; //打印链表while(cur){printf("%d--->",cur->data);cur = cur->next;}printf("NULL\n");}void DestoryLinklist(pLinklist *pL){assert(pL != NULL); //摧毁链表pLinklist cur = *pL;pLinklist pre = NULL;if (*pL == NULL){printf("链表为空");return ;}if (cur->next = NULL){*pL = NULL;free(cur);cur = NULL;return ;}while(cur){pre = cur;cur = cur->next;free(pre);pre = NULL;}}pLinklist reverseLinklist(pLinklist *pL){if((*pL) == NULL || pL == NULL){return NULL;}if((*pL)->next == NULL){return *pL;}Linklist *p = *pL;Linklist *q = (*pL)->next;Linklist *r = *pL;while(q->next != NULL){r = q->next;q->next = p;p = q;q = r;r = r->next;}q->next = p;(*pL)->next = NULL;*pL = q;return *pL;}第⼀步就是判断这个单链表是否为空,因为我⽤了⼆级指针,因此要看链表为空的同时还要看pL是否指向有问题。

C语言数据结构实现链表逆序并输出

C语言数据结构实现链表逆序并输出

C语言数据结构实现链表逆序并输出c语言数据结构实现链表逆序并输出实例代码:头文件:#include<stdio. h>ftinclude<stdlib. h> #include<malloc・ h> typedefintElemType; typedefstructNode{//结点结构ElemTypevalue; //值域structNode*next; //指针域}Node, *ptr_Node;typedefstructLinkList{//链表结构ptr_Nodehead;//链表头结点指针ptr_Nodetail;//链表尾结点指针intlength;//链表长度}LinkList, *ptr_LinkList; ptr_LinkLi stCreateList(void) {//创建一个空琏表ptr_LinkListlinklist;linklist=(LinkList*)malloc(sizeof(LinkList));if (!linklist){printf("allocationfailed. \n");linklist-〉head二NULL;linklist->tail=XULL;linklist->length=O;returnlinklist;}boolIsListEmpty(ptr_LinkListlinklist){//判断链表是否为空if(linklist->length==0){returntrue;}returnfalse;}voidlnsertListHead(ptr_LinkListlinklist, ElemTypeelement) {//在表头插入值为element的结点作为新的表头ptr_Nodeptr_node;ptr_node= (Node*)malloc(sizeof (Node)) ;//生成插入结点if (!p t:r_node) printf(^allocationfailed. \n");}elseptr_node~>value=element;if (linklist->length==0){linklist-〉head二ptr_node;linklist->tail=linklist~>head;1inklisl->next=NULL;}else{ptr_node~>next=linklist~>head;1 inklist->head=p tr_node; / / 链表头}linklist->length++;//^ 表长度加 1}} voidlnsertListTail(ptr_LinkListlinklist, ElemTypeelement) ptr_Nodeptr_node;ptr_node= (Node*)malloc(sizeof (Node)) ;//生成插入结点if(!ptr_node){printf("allocationfailed. \n");}else{ptr_node->value=element;if (linklis t - >length=0){linklist一>head二ptr_node;linklist->tail=linklist一>head;1 inklist->tail->next=NULL;}else{1 inklist->tail~>next=ptr_node;linklist->ta 订二ptr_node; // 链表尾}linklist->length++;// 链表长度加 1}}voidlnsertListPosition(pt:r_LinkListlinklist, intpos, ElemT ypeelement){inti;ptr_Nodeptr_node;ptr_Nodetemp_ptr_node;if(pos<l :pos>linklist->length){printf ("Theinsertpositionisinvalidate・ \n〃);}else{ptr_node= (Node*)malloc(sizeof (Node)) ;//生成插入结点if(!ptr_node){printf(^allocationfailed. \n");}ptr_node->value=element;if (pos==l)InsertListHead(linklist, element);}elseif(pos==linklist->length)InsertListTail(linklist,element);}else{temp_ptr_node=linklist->head;for (i=l;i<pos-l;i++){//找到第posT个结点temp_ptr_node二temp_pt:r_node->next;}ptr_node->next二temp_ptr_node->next; temp_ptr_node->next二ptr_node; linklist->length++;}}}voidDestroy(ptr_LinkListlinklist) {//销毁链表ptr_Nodep=linklist->head; ptr_Nodeq;while(p){//释放每个结点空间q=p->next;free (p);p二NULL;P 二q;}}voidTraverse(ptr_LinkListlinklist){//输出整个链表ptr_Nodep;p二linklist-〉head;while(p){printf("%4d", p->value);p=p->next;}}头文件中实现了链表的几个基本的操作,有的是必须的,有些是非必须的。

数据结构c语言版(题目)

数据结构c语言版(题目)

分类:编程思想和算法2012-09-15 22:24 1759 人阅读评论(0)收藏举报如果TCPhashlistJuli 采用线性表的顺序存储结构,则可以随机存取表中任一终端,但插入和删除终端时,需要移动大量元素,巧妙地终端离线不进行删除操作。

数组,存储的元素应该是线性表顺序存储结构的数据结构。

线性表题目类型:线性表在顺序结构上各种操作的实现;线性链表的各种操作;两个或多个线性表的各种操作;循环链表和双向链表;稀疏多项式及其运算在线性表的两种存储结构上的实现。

线性表在顺序结构上各种操作的实现题目1:(线性表顺序存储结构上的操作—Delete )从顺序存储结构的线性表a 中删除第i个元素起的k个元素。

(《数据结构题集C语言版》P16)题目2:(线性表顺序存储结构上的操作_lnsert )设顺序表va中的数据元素递增有序。

试写一算法,将x插入到循序表的适当位置上,以保持该表的有序性。

(《数据结构题集C语言版》P17)题目3:(线性表顺序存储结构上的操作_逆置)试写一算法,实现顺序表的就地逆置,即利用原表的存储空间将线性表逆置。

(《数据结构题集C语言版》2.21)线性表线性链表的各种操作题目1:( Insert )试写一算法,在无头结点的动态单链表上实现线性表的Insert(L,i,b), 并和在带头结点的动态单链表上实现同样操作的算法进行比较。

(《数据结构题集C语音版》P17)题目2:(Delete )同上题要求,实现线性表操作Delete(L,i).题目3:已知线性表中的元素以值递增有序排序,并以单链表作为存储结构。

试写一高效算法,删除表中所有值大于mink且小于maxk的元素(若表中存在这样的元素)同时释放被删除结点空间,并分析你的算法的事件复杂度(注意:mink和maxk是给定的两个参变量,它们的值可以和表中的元素相同,也可以不同)。

(《数据结构题集C语言版》P17)题目4:同上题条件,试写一高效算法,删除表中所有值相同的多余元素(使得操作后的线性表所有元素的值均不相同),同是释放被删结点空间,并分析你算法的时间复杂度。

单链表的逆置

单链表的逆置

单链表的逆置单链表的逆置是⾯试官⾮常青睐的题,这个题可以看出⾯试者对链表和指针的操作。

⽽且问题也很好描述,⼀句话就表达出了⾃⼰的题。

----------------------------------------------------------------------------------------------⼀、算法思想:(头插法)<1>,将源链表分为链表头和链表实体。

<2>,将链表实体节点⽤头插法依次插⼊到链表头中。

<3>,如果链表实体插完则算法结束,否则转到<2>.--------------------------------------------------------------------------------------------⼆、算法的实现:头插法:void reverse(struct node *head){if (head == NULL)return ;struct node *p = head->next,*pnext = NULL;head->next = NULL;while (p != NULL) {pnext = p->next;p->next = head->next;head->next = p;p = pnext;}return ;}利⽤辅助指针void ListReverse2(LinkList L){LNode *real = L->next; //带头结点的链表,real指向第⼀个实结点//real为NULL,则链表为只含头结点的空表//real->nexxt为NULL,则链表只含有⼀个结点if(real == NULL || real->next == NULL)return;LNode *pre = real; //先前指针LNode *cur = real->next; //当前指针LNode *suc = NULL; //后继指针while(cur != NULL){suc = cur->next;cur->next = pre;pre = cur;cur = suc;}real->next = NULL; //while执⾏后第⼀个结点和第⼆个结点互指L->next = pre; //记录新的头结点}。

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

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

实现单链表的就地逆置算法题目:有一个线性表(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;}。

单链表的逆序(反转)

单链表的逆序(反转)

单链表的逆序(反转)单链表的逆序,本来不是算法这一部分的,怎奈何小伙伴们说,面试考的机率比较大,故此就把它跟算法放到一起了。

关于单链表逆序的基本知识点,请参加:/autumn20080101/article/details/7607148 当您看了上面博文的一部分,就能基本了解的时候,下面的内容应该适合您了。

下面的内容是对单链表逆序的关键知识点的一个总结。

博主客人觉得,单链表最关键的是本节点有一个指向下一个节点的指针(即后继节点指针),双向链表则是本节点有一个前驱节点和一个后继节点。

单链表时通过while循环,从头节点开始,直到节点的后继节点为空时,则到达了链表的尾部。

其实,单链表逆序,靠的就是下面的关键代码:1 while (head != NULL) {2 //在头节点改变之前,先获取下一个节点的指针3 next = head->Next;4 //头节点的下一个节点要改成它的上一个节点,是一个逆转的过程5 head->Next = prev;6 //上一个节点前移指向头节点7 prev = head;8 //头节点前移指向下一个节点9 head = next;10 }开发环境为:qt, c语言代码:完整代码:1 #include <QCoreApplication>23 //定义常数值4 #define LEN 35 const int MAX_NUM = 5;67 //定义节点8 //typedef struct tagNode* linkNode;9 typedef struct tagNode{10 int key;11 char value[LEN];12 struct tagNode* Next;13 } *Node, *linkList;1415 //生成链表16 linkList generateLinkList();17 //释放链表18 void freeLinkList(linkList list);19 //反转链表20 Node ReverseLinkList(Node head);21 //打印链表22 void printLinkList(linkList list);2324 int main(int argc, char *argv[])25 {26 QCoreApplication a(argc, argv);27 //生成链表28 Node head = generateLinkList();29 printf("反转之前的链表\r\n");30 //打印链表31 printLinkList(head);32 //链表反向33 head = ReverseLinkList(head);34 printf("反转之后的链表\r\n");35 //打印反向后的链表36 printLinkList(head);37 //释放链表内存38 freeLinkList(head);39 return a.exec();40 }41 /**42 * @函数名:generateLinkList43 * @参数:无44 * @返回值:链表对象指针(首节点)45 * @用途:生成链表对象46 * @作者:yangfy47 */48 linkList generateLinkList()49 {50 Node head, prev;51 //头节点52 head = (Node)malloc(sizeof(Node));53 head->key = 1;54 snprintf(head->value, LEN - 1, "%c", 65);55 //prev初始指向头节点56 prev = head;57 //初始化链表元素58 for(int i = 1; i < MAX_NUM; i++){59 Node pNode = (Node)malloc(sizeof(Node));60 //形成链表数据61 pNode->key = i + 1;62 pNode->Next = NULL;63 snprintf(pNode->value, LEN - 1, "%c", 65 + i);64 //前一个节点的下一个节点指向本节点(pNode)65 prev->Next = pNode;66 //把前一个节点置为本节点,进入下一个循环67 prev = pNode;68 }69 return head;70 }71 /**72 * @函数名:freeLinkList73 * @参数:head:头节点指针74 * @返回值:无75 * @用途:链表指针内存资源的释放。

数据结构C语言版顺序表和单链表的逆置精编WORD版

数据结构C语言版顺序表和单链表的逆置精编WORD版

数据结构C语言版顺序表和单链表的逆置精编W O R D版IBM system office room 【A0816H-A0912AAAHH-GX8Q8-GNTHHJ8】实验1-1 顺序表的逆置操作程序原码#include<stdlib.h> // 创建顺序表,确定元素个数,插入各个元素,逆置列表。

#include<stdio.h>#include<malloc.h>#define max_list_size 100 //定义给顺序表分配空间大小typedef struct{int *elem;int length;}list_node; //指向顺序表首地址的结构体单元list_node L; //这里使用了全局变量,在所有的函数里可以随意修改其值int list[max_list_size];void init(); // 初始化操作void inversion(); // 倒置部分void creat(); // 建表部分void display(); // 显示部分//*************主函数******************int main(){init();creat();printf("\n您输入的顺序表的结点数: \n");display();inversion();printf("\n倒置顺序表的结点数: \n");display();}//*************初始化操作分配空间****************** void init(){L.elem = (int *) malloc (max_list_size * sizeof(int) );if (! L.elem) {printf("顺序表已满");exit(-1);}L.length = 0;}//*************以下为建表部分******************void creat(){int a, b, i;printf("请输入顺序表的结点数: ");scanf("%d", &a);if(a<=0){printf("顺序表个数要为正整数!请重新输入: ");scanf("%d",&a);}if( a > max_list_size - 1 || a < 0 ){printf("分配失败,退出程序! \n");exit(1);}for( i = 0; i != a; ++i){printf("请输入第%d结点的值: ", i+1);scanf("%d", &b);L.elem[i] = b;++L.length;}}//****************以下为倒置部分**********************void inversion(){int a, b, i;a = L.length;for( i = 1; i <= a/2; i++){b = L.elem[i-1];L.elem[i-1] = L.elem[a-i];L.elem[a-i] = b;}}//****************以下为显示部分********************** void display(){int i;for( i = 1; i <= L.length; ++i)printf("%d\t", L.elem[i-1]);printf("\n");}实验1-1 测试结果输入一个正数、输入一个负数、实验1-2 单链表的逆置操作程序原码//创建一个单链表,确定元素个数,插入各个元素,进行逆置操作,并输出。

单链表原地逆置算法

单链表原地逆置算法

单链表原地逆置算法单链表是一种常见的数据结构,由一系列节点组成。

每个节点包含一个数据域和一个指向下一个节点的指针。

原地逆置指的是在不创建新的链表的情况下,只对原有链表节点的指针进行调整,使得链表中的节点以相反的顺序排列。

下面将详细介绍单链表原地逆置的算法。

1.定义所需的数据结构首先,我们需要定义一个单链表的节点结构,包含数据域和指针域。

```C++struct ListNodeint val;ListNode* next;ListNode(int x) : val(x), next(nullptr) {}};```2.创建一个示例链表为了方便演示算法,我们创建一个简单的示例链表。

```C++ListNode* createListListNode* head = new ListNode(1);ListNode* node2 = new ListNode(2);ListNode* node3 = new ListNode(3);ListNode* node4 = new ListNode(4);ListNode* node5 = new ListNode(5);head->next = node2;node2->next = node3;node3->next = node4;node4->next = node5;return head;```3.原地逆置算法实现原地逆置算法的核心思想是将每个节点的next指针指向前一个节点,需要保留当前节点的下一个节点的指针,用于遍历整个链表。

```C++ListNode* reverseList(ListNode* head)ListNode* prev = nullptr; // 前一个节点指针ListNode* curr = head; // 当前节点指针while(curr != nullptr)//临时保存下一个节点ListNode* nextTemp = curr->next;//将当前节点的指针指向前一个节点curr->next = prev;//更新指针,向后移动prev = curr;curr = nextTemp;}return prev; // 返回新链表的头节点```4.测试为了验证原地逆置算法的正确性,我们调用createList函数创建一个示例链表,并调用reverseList函数进行逆置操作。

单链表逆置代码

单链表逆置代码

//* * * * * * * * * * * * * * * * * * * * * * * *//*CHAPTER :2 (2_2) *//*PROGRAM :链式结构的线性表*//*CONTENT :生成,插入,删除,定位,查找*//* * * * * * * * * * * * * * * * * * * * * * * *#include <conio.h>#include <dos.h>#include <stdio.h>#include <stdlib.h>#define LEN sizeof(LNode) //定义LEN为一个节点的长度enum BOOL{False,True}; //定义BOOL型typedef struct node{char data; //数据域struct node *next;//指向下一个节点的指针}LNode,*LinkList;void CreatList(LinkList &,int); //生成一个单链表BOOL ListInsert(LinkList &,int,char); //在单链表中插入一个元素BOOL ListDelete(LinkList &,int,char &); //在单链表中删除一个元素BOOL ListFind_keyword(LinkList,char,int &); //按关键字查找一个元素BOOL ListFind_order(LinkList,char &,int); //按序号查找一个元素void ListPrint(LinkList); //显示单链表所有元素void inverse(LinkList &);void main(){LinkList L;BOOL temp;int num,loc,flag=1;char j,ch;// textbackground(3); //设置屏幕颜色//textcolor(15);// clrscr();//---------------------程序解说-----------------------printf("本程序实现链式结构的线性表的操作。

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