倒置单链表的算法
单链表的逆置(头插法,就地逆转)
单链表的逆置(头插法,就地逆转)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指向下一个要遍历的节点。
单链表倒序算法
单链表倒序算法#include <iostream>#include <stdio.h> using namespace std;struct st{int a;st(int i){ a = i; }struct st* next;};void sort(struct st* &head){st* p = 0;//排序后的链表头st* p1 = head;//排序前的链表头st* p2 = p1;//在排序过程中,保存原始链表头for(;p2;){p2 = p1->next;p1->next = p;//以上2步,是将当前节点从链表中取出然后将指针反向指向 p = p1;//将排序好的链表的头,给pp1 = p2;//将p1重新指向链表的首位置}head = p;//让head重新指向排序好的链表头}void print(struct st* p){for(;p;){cout << p->a << endl;p = p->next;}}int main( void ){st* head = new st(0);st* p = head;p->next = new st(1);p = p->next;p->next = new st(2);p = p->next;p->next = new st(3);p = p->next;p->next = 0;print(head);sort(head);cout << "----------------------" << endl;print(head);return 0;}//20070126=====================可能这么说更好理解点:实际上可以看作是2个list.,从原始list的head开始逐个取节点,然后向目的list的头的位置插入。
单链表的逆置的实现
| 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)
数据结构单链表、双链表的逆置算法
数据结构与算法的课程设计课程设计题目:数据结构的逆置算法院系名称:信息技术学院专业(班级):计算机2班姓名:学号:指导教师:实验内容:分别用一维数组,单链表,双链表实现逆置(一)使用一维数组实现逆置1.需求分析:定义一个一维数组(整型),用for语句实现循环,给数组元素赋值,并将数组元素逆序输出。
2.详细设计:main(){ int a[3],i; /*定义元素个数为3的一维数组*/for(i=0;i<3;i++)scanf("%d",&a[i]);for(i=2;i>=0;i--)printf("%d ",a[i]);getch();}3.运行及调试:4.附录:#include<stdio.h>void main(){ int a[3],i; /*定义一维数组*/for(i=0;i<3;i++)scanf("%d",&a[i]);for(i=2;i>=0;i--)printf("%d ",a[i]);getch();}(二)单链表实现逆置1.需求分析:创建一个单链表并实现逆序输出2.详细设计:定义的所有数据类型,对每个操作写出伪码算法;对主程序和其他模块也都写出伪码算法。
(1)单链表的定义typedef struct node{ int data;/*数据域为整型*/struct node* next; /*定义结点的指针域*/}LinkList;/*数据结点*/(2)头插法建立单链表Tnode *CreatList(){ Tnode *head; /*头指针*/LinkList *p;/*工作指针/int ip;head=(Tnode *)malloc(sizeof(Tnode));head->next=NULL;/*链表开始为空*/printf("please input the number:\n");scanf("%d",&ip); /*向链表中添加元素*/while(ip!=000){ p=(LinkList *)malloc(sizeof(LinkList));/*生成新结点*/ p->data=ip; /*将值赋给新生结点*/p->next=head->next;head->next=p;scanf("%d",&ip);}if(ip==000) /*当输入的数值为000时结束*/printf("\nthe ip is end!\n\n");return head;}(3)读取链表中的数据void ReadList(Tnode *head){ LinkList *p;p=head->next;while(p){ printf("%d ",p->data);p=p->next;}printf("\n");}(4)链表的倒置void ExchangeList(Tnode *head){ LinkList *r,*s;r=head->next;head->next=NULL;while(r){ s=r->next;r->next=head->next;head->next=r;r=s;}3.运行及调试5.附录:/*带头结点的链表建立*/#include<stdio.h>#include<malloc.h>#include<conio.h>typedef struct node /*结点类型定义*/{ int data; /*结点的数据域*/struct node* next; /*结点的指针域*/}LinkList;/*数据结点*/typedef struct{ int length; /**链表的长度/struct node*next; /*结点的指针域*/}Tnode; /*头结点*/Tnode *CreatList()/*头插法建立单链表*/{ Tnode *head;LinkList *p;/*工作指针*/int ip;head=(Tnode *)malloc(sizeof(Tnode));head->next=NULL; /*链表开始为空*/printf("please ip the number:\n");scanf("%d",&ip);while(ip!=000){ p=(LinkList *)malloc(sizeof(LinkList)); /*生成新结点*/ p->data=ip; /*将元素值赋给新生结点p*/p->next=head->next;head->next=p; /*head指向p结点*/scanf("%d",&ip);if(ip==000)printf("\nthe ip is end!\n\n");return head;}void ReadList(Tnode *head) /*读取链表中的数据*/{ LinkList *p;p=head->next;while(p){printf("%d ",p->data);p=p->next;}printf("\n");}void ExchangeList(Tnode *head) /*链表的倒置*/{ LinkList *r,*s;r=head->next;head->next=NULL;while(r){ s=r->next;r->next=head->next;head->next=r;r=s;}}void Readme(){ printf("press 1 to set libiao\n");printf("press 0 to exit\n");printf("-------------------------------------------------------------------------------\n"); }void main(){ Tnode *head;int choice;while(choice){ Readme();scanf("%d",&choice);switch(choice){ case 1:head=CreatList(); /*创建单链表*/printf("the number are:\n\n");ReadList(head);printf("\n");ExchangeList(head); /**逆置后的单链表/printf("the exchange number are:\n\n"); /*打印逆置后的单链表*/ReadList(head); /*读取单链表中的数据*/getch();break;}}}(三)双链表实现逆置1.需求分析:创建一个双链表并实现逆序输出2.详细设计:定义的所有数据类型,对每个操作写出伪码算法;对主程序和其他模块也都写出伪码算法。
单链表逆置原理
单链表逆置原理
单链表逆置原理是通过改变链表中节点的指向,将链表中的节点重新排列,使得原来链表的顺序颠倒过来。
具体实现方法是使用三个指针,一个指向当前节点,一个指向上一个节点,一个指向下一个节点。
通过交换当前节点的下一个节点和上一个节点的下一个节点,实现节点的逆置。
在每一轮循环中,用p3记录p2的next位置,将p2的next指向p1,最后让p1指向p2,p2指向p3。
整个循环结束以后,p2停留在原来链表尾部的NULL处,p1停留在原来链表的最后一个元素。
其特点包括:
1.改变原链表的顺序:通过逆置操作,可以将单链表的顺序完全颠倒,变
为反向的顺序。
2.操作简单:相对于其他数据结构,单链表的逆置操作相对简单,只需要
遍历链表并交换相邻节点的指向即可。
3.对原链表无影响:逆置操作不会改变原链表中节点的值,只是改变了它
们的指向,因此不会对原链表造成任何影响。
4.适用于需要反向存储的数据结构:单链表的逆置操作可以用于需要反向
存储的数据结构,如某些算法或数据压缩等应用中。
需要注意的是,单链表的逆置操作需要小心处理边界条件和错误情况,例如链表为空或只有一个节点等情况。
同时,在逆置操作过程中需要注意内存管理,避免出现内存泄漏等问题。
编写算法:实现带头结点单链表的逆置算法
编写算法:实现带头结点单链表的逆置算法引言单链表是一种常见的数据结构,它由一系列节点组成,每个节点包含两部分:数据域和指针域。
其中,数据域用于存储数据,指针域用于指向下一个节点。
在单链表中,头结点是第一个节点之前的一个特殊节点,它不存储任何数据。
逆置(或反转)单链表是将原始链表中的节点顺序颠倒过来。
例如,给定一个单链表: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;}```通过以上步骤,我们可以实现单链表的就地逆置算法。
实现单链表的倒置(两种方法)
# conding:utf8 class Node():
def __init__(self, _item): self.item = _item self.next = None
实现单链表的倒置(两种方法)
class Link(): def __init__(self): self._head = None
link.travel()
输出结果:
1 2 3 --------------------------3 2 1
def travel(self): cur = self._head while cur: print(cur.item) cur = cur.next
# 方式一:三个变量实现单链表倒置 def reverse1(self):
Hale Waihona Puke pre = None cur = self._head next_node = cur.next while cur:
temp = cur.next cur.next = pre pre = cur cur = temp self._head = pre
if __name__ == "__main__": link = Link() link.append(1) link.append(2) link.append(3) link.travel() print("---------------------------") link.reverse1()
cur.next = pre pre = cur cur = next_node if next_node:
单链表的逆置(C++实现)
单链表的逆置(C++实现) 单链表以及逆置是什么就不说了,就简单说⼀下思想:链表的初始状态:具体的⽅法就是将头节点后⾯的节点,依次通过指针指向,插⼊head头节点之后,即可完成逆置过程. ⽰意图(这⾥我写⼀下中间处理流程,因为这样⽐较直观.第⼀次的处理与正常处理雷同):需要注意的主要有两点:1. 逆置之后的链表的尾部要NULL.在这⾥就是刚开始的时候的pHead->next->next = nullptr,具体可参考实现代码.2. 当curr指向最后⼀个节点时,需要特殊处理⼀下.实现代码:#include <iostream>using namespace std;template <typename T>struct Node{Node(T t){data = t;}T data;Node *next;};template <typename T>class List{public:List(){CreatList();}~List(){Node<T> *start = head;Node<T> *end = start->next;while (end){delete start;start = end;end = end->next;}delete start;}void CreatList(){head = new Node<T>(-100);Node<T> *temp = nullptr;rear = head;for (int i = 0; i < 10; i++){temp = new Node<T>(i);temp->next = nullptr;rear->next = temp;rear = temp;}rear->next = nullptr;}void ReverseList(){Node<T> *curr, *beh;curr = head->next;rear = head->next;beh = curr->next;while (beh){curr->next = head->next;head->next = curr;curr = beh;beh = beh->next;}curr->next = head->next;/*处理`curr`指向最后⼀个节点*/ head->next = curr;/*处理链表的尾部 nullptr */rear->next = nullptr;}void Print(){Node<T> *temp = head->next;while (temp){std::cout << temp->data << " ";temp = temp->next;}std::cout << std::endl;}private:Node<T> *head;Node<T> *rear;};int main(void){List<int> list;list.Print();list.ReverseList();list.Print();}运⾏结果:附录:顺便⽤⼀下valgrind这个内存检测⼯具我们去掉析构函数,并使⽤:valgrind --tool=memcheck --leak-check=full --show-reachable=yes --trace-children=yes ./a.out其中–leak-check=full 指的是完全检查内存泄漏,–show-reachable=yes是显⽰内存泄漏的地点,–trace-children=yes是跟⼊⼦进程。
单链表的逆置c语言算法
单链表的逆置c语言算法单链表的逆置C语言算法前言:单链表是一种常用的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。
单链表的逆置是指将链表中的节点顺序颠倒,即原链表的第一个节点变为新链表的最后一个节点,原链表的最后一个节点变为新链表的第一个节点。
逆置链表在实际应用中有着重要的作用,例如链表的搜索、排序和删除等操作。
算法思路:对于单链表的逆置,我们可以利用三个指针来辅助完成。
假设原链表为A->B->C->D->NULL,逆置后的链表为D->C->B->A->NULL。
初始时,我们定义三个指针:当前指针cur指向当前节点A,前一个指针prev指向当前节点的前一个节点(初始时为NULL),下一个指针next指向当前节点的下一个节点(初始时为B)。
然后,我们将当前节点的指针指向前一个节点,即将A->B的指针改为A<-B。
接下来,我们将prev指针指向当前节点,即prev指向A。
最后,我们将cur指针指向next节点,即cur指向B。
重复以上操作,直到cur指针指向NULL,即遍历完整个链表。
最后,我们返回prev指针,即逆置后的链表的头节点。
具体实现:下面是单链表逆置的C语言代码实现:```c#include <stdio.h>#include <stdlib.h>// 定义链表节点结构体typedef struct Node {int data; // 节点数据struct Node* next; // 指向下一个节点的指针} Node;// 创建链表节点Node* createNode(int data) {Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = data;newNode->next = NULL;return newNode;}// 逆置链表Node* reverseList(Node* head) {Node* prev = NULL;Node* cur = head;Node* next = NULL;while (cur != NULL) {next = cur->next; // 保存当前节点的下一个节点cur->next = prev; // 当前节点的指针指向前一个节点 prev = cur; // prev指针指向当前节点cur = next; // cur指针指向下一个节点}return prev; // 返回逆置后的链表头节点}// 打印链表void printList(Node* head) {Node* cur = head;while (cur != NULL) {printf("%d -> ", cur->data);cur = cur->next;}printf("NULL\n");}int main() {// 创建链表 A->B->C->D->NULLNode* head = createNode(1);head->next = createNode(2);head->next->next = createNode(3);head->next->next->next = createNode(4);printf("原链表:");printList(head);// 逆置链表Node* newHead = reverseList(head);printf("逆置后的链表:");printList(newHead);return 0;}```运行结果:原链表:1 -> 2 -> 3 -> 4 -> NULL逆置后的链表:4 -> 3 -> 2 -> 1 -> NULL总结:通过三个指针的相互转换,我们可以实现单链表的逆置。
9.9单链表之链表反转
9.9单链表之链表反转9.9单链表之链表反转单链表反转的四种经典算法迭代反转链表递归反转链表头插法反转链表就地逆置法反转链表主要⽰例的是:不带头节点的链表反转链表反转图⽰图解:起始链表:反转后链表:迭代反转链表具体实现:设置三个指针,分别指向⾸元节点、⾸元节点直接前驱、⾸元节点后继--->beg、mid、end 循环开始修改mid的指针域令其指向beg将三个指针整体向后移动⼀个节点循环重复。
当end为空,更改mid指针域,跳出循环更改头指针位置⼀个流程实现图⽰:设置三个指针:更改mid指针指向,整体向后移动⼀个节点:最后⼀个节点:迭代反转算法C语⾔的实现:/*1、head为⽆头节点链表的头指针*/Link * iterator_reverse(Link * head){//判断头指针是否有指向⾸元节点if (head==NULL||head->next==NULL){//返回头指针return head;}else {//设置三个指针--->beg、mid、end。
分别指向⾸元节点前⾯的空节点、⾸元节点、⾸元节点的下⼀位Link * beg = NULL;Link * mid = head;Link * end = head->next;//循环执⾏while (true){//修改mid指针域指向前⼀个指针mid->next = beg;//判断end是否为空--->mid是否是在最后⼀个节点了if (end == NULL){//结束循环break;}//三个数整体向后移动⼀个节点beg = mid;mid = end;end = end->next;}//修改head头指针的指向,指向midhead = mid;//返回头指针--->⽤于找到链表return head;}}递归反转链表本质:如果把NULL看成⼀个变量相当于把NULL这个变量从最后移动到⾸元节点之前具体实现:通过判断头节点和头节点的指针域是否为空决定是否返回头节点通过递归的⽅式找到最后⼀个节点,此时会返回头节点并且创建新的数据域节点第⼀次开始进⾏NULL反转的时候起始位置是在倒数第⼆个节点,创建的临时节点是指针域让指针域的下⼀位指向⾃⾝,⾃⾝的指针域指向NULL--->这样结束的时候就会递归执⾏递归反转实现流程:指针域∧表⽰为 NULL递归找到最后⼀个节点:从倒数第⼆个节点开始创建新的预留节点:⼀直递归重复到⾸元节点:递归反转算法C语⾔实现:Link * recusive_reverse(Link * head){//判断递归返回的节点是否是最后⼀个节点if (head == NULL || head->next == NULL){//返回头节点return head;}else{//⼀直创建新节点Link * new_head = (Link*)malloc(sizeof(Link));//当逐层退出时,new_head 的指向都不变,⼀直指向原链表中最后⼀个节点;//递归每退出⼀层,函数中 head 指针的指向都会发⽣改变,都指向上⼀个节点。
【数据结构复习】链表的倒置(头插法倒置)
【数据结构复习】链表的倒置(头插法倒置)#include <bits/stdc++.h>using namespace std;typedef int ElemType;struct LNode{ElemType data;LNode *next;};LNode *head,*tail;void init(){head = (LNode*)malloc(sizeof(LNode));head->next = NULL;tail = head;}void input_data(){int x;cin >> x;while (x!=-1){LNode *temp = (LNode*)malloc(sizeof(LNode));temp->data = x;temp->next = NULL;tail->next = temp;tail = temp;cin >> x;}}//关键函数void _reverse(){LNode *p = head->next;head->next = NULL;while (p){LNode *temp = p->next;//记录下当前遍历到的这个节点的下⼀个p->next = head->next;//这个⼏点的下⼀个节点接在头结点后⾯的那个节点head->next = p;//头结点的后⼀个节点指向该节点,从⽽完成插⼊过程p = temp;}}void print(){LNode *temp = head->next;while (temp){cout<<temp->data<<" ";temp = temp->next;}}int main(){init();//freopen("D://rush.txt","r",stdin);input_data();_reverse();print();fclose(stdin);return 0;}。
将单链表进行倒置的算法
将单链表进行倒置的算法说起将单链表倒置这个事儿,我得先从我那会儿在大学教书那会儿讲起。
那时候,计算机系的小子们,一个个都像是刚从山里出来的猴子,对啥都好奇,特别是算法,眼睛里都冒着光。
我呢,也就顺着他们的性子,时不时地给他们扔个骨头,哦不,是出个难题,让他们啃一啃。
那天,阳光正好,教室里闷得跟蒸笼似的,学生们一个个汗流浃背,却还瞪大眼睛,生怕错过我一丁点儿的讲解。
我就那么往讲台上一站,手里拿着根粉笔,也不着急写字,就先问了一句:“你们说,单链表倒置,这事儿难不难?”底下立马就有机灵鬼喊道:“难!老师,这比爬树还难!”我一乐,心想这小子是真会找乐子,便接着说:“难?难也得给我啃下来!不过呢,咱们今天不讲那些高深莫测的理论,就来个土法炼钢,让你们瞧瞧,这倒置单链表,其实就跟咱们老家那倒腾粮食袋子似的,简单得很!”说着,我就开始在黑板上画起了图,一边画一边讲:“看这,一个节点接一个节点,跟咱们排队买冰棍似的,一个挨一个。
现在,咱们要把队伍倒过来,怎么倒?你不能一个个地喊名字让他们回头吧?那得乱套了!”学生们听得津津有味,有的还点头,有的则是一脸茫然,估计还在琢磨冰棍的事儿呢。
我也不管他们,继续往下说:“咱们得有个头儿,就是咱们说的那个头节点,然后,咱们就从最后一个开始,一个个地往前挪,这不就倒过来了嘛!”说完,我转身看向他们,问:“明白没?”有几个反应快的,立马就嚷嚷开了:“明白了!就像咱们过年包饺子,最后一个包完,往前面一放,不就成了嘛!”我一听,这比喻打得挺好,便笑着说:“对头!就是这么个理儿!不过呢,咱们在计算机里,可不能真用手去挪,得用代码,用指针,让电脑去干这活儿!”接着,我就开始写代码,一边写一边解释:“咱们先设个指针,指向最后一个节点,然后再设个新的头儿,把这个最后一个节点接上去。
然后,原来的最后一个节点,就成了新的头儿了,咱们再让它指向前一个节点,以此类推,直到咱们把所有的节点都倒过来。
链表的倒置以及查找 数据结构试验来的哦
实验一线性表实验目的1、掌握线性表的逻辑结构和物理实现;2、掌握线性表的顺序存储结构和链式存储结构,熟悉对线性表的基本操作;3、在学有余力的情况下,掌握循环链表的实现及其基本操作;4、根据实验要求设计并完成程序,把理论的基本操作知识转化到实际的实践应用中。
课题一的具体实验内容1、构造元素类型为整型的线性表,将以下元素插入分别插入线性表:<34 56 20 9 15 5>2、查找表中是否存在元素20,实现元素20与元素9的交换;3、按照课题要求编写函数,实现线性表元素<34 56 9 20 15 5>的倒置,即倒置后的表应为< 5 15 20 9 56 34 >。
主程序代码(仅供参考,勿用于商业用途)#include<stdio.h>#include<stdlib.h>#define NULL 0struct node{int num;struct node *next;};void main(){int i,flag=1;struct node *L,*s,*p,*h,*q,*k,*p1,*temp;L=(node*)malloc(sizeof(struct node));p=L; printf("请输入\n");for(i=0;i<6;i++){s=(node*)malloc(sizeof(struct node));scanf("%d",&s->num);p->next=s;p=s;}p->next=NULL; //以上是链表的建立和输入//以下为a元素交换p=L;while(p->next->num!=20&&p->next->next!=NULL) p=p->next;if(p->next->next==NULL){printf("sorry,can not find!\n");flag=0;printf("原表括倒置后输出\n");}else if (p->next->num==20){flag=1;printf("find it!\n");}if(flag==1){h=p->next;p->next=p->next->next;h->next=p->next->next;p->next->next=h;//以下为链表括的输出printf("交换后输出\n");while(p!=NULL){printf("%d ",p->num);p=p->next;}printf("倒置后输出\n");}//以下为链表括的倒置p1=L->next;temp=p1->next;p1->next=NULL;p=temp;while(temp!=NULL){ p=p->next;//移动原链表的指针?temp->next=p1;L->next=temp;p1=temp;//需插入节点的指向移动temp=p;}//以下为链表输出while(p!=NULL){printf("%d ",p->num);p=p->next;}printf("\n");}。
java实现单链表反转(倒置)
java实现单链表反转(倒置)据说单链表反转问题⾯试中经常问,⽽链表这个东西相对于数组的确稍微难想象,因此今天纪录⼀下单链表反转的代码。
1,先定义⼀个节点类。
1 public class Node {2 int index;3 Node next;45 public Node(int index, Node next) {6 this.index = index;7 this.next = next;8 }9 }2,我⼀共写了三种⽅法(1)迭代法。
先将下⼀节点纪录下来,然后让当前节点指向上⼀节点,再将当前节点纪录下来,再让下⼀节点变为当前节点public Node reverse(Node node) {Node prev = null;Node now = node;while (now != null) {Node next = now.next;now.next = prev;prev = now;now = next;}return prev;}(2)递归⽅法1。
先找到最后⼀个节点,然后从最后⼀个开始反转,然后当前节点反转时其后⾯的节点已经进⾏反转了,不需要管。
最后返回原来的最后⼀个节点public Node reverse2(Node node, Node prev) {if (node.next == null) {node.next = prev;return node;} else {Node re = reverse2(node.next, node);node.next = prev;return re;}}(3)递归⽅法2。
先找到最后⼀个节点,然后从最后⼀个节点之前的那个节点的⽅法体中开始将下⼀个指向当前⼀个,然后当前节点反转时其后⾯的节点已经进⾏反转了,不需要管。
最后返回原来的最后⼀个节点。
public Node reverse3(Node node) {if(node.next==null)return node;Node next = node.next;node.next = null;Node re = reverse3(next);next.next = node;return re;}总结:迭代法思路很清晰,就是将当前节点和下⼀节点保存起来,然后将当前节点反转;递归法1是先找到最后⼀个节点进⾏反转,然后再反转之前的节点时就不⽤担⼼丢失以后的节点了,只需要关⼼本节点的反转;递归法2是同理,只是反转动作是从最后⼀个节点的前⼀个节点开始的。
单链表反转(4种算法实现)
单链表反转(4种算法实现)反转链表,又可以称为翻转或逆置链表,它们表达的是同一个意思。
以图 1 所示的链表为例经过反转(翻转、逆置)后,得到的新链表如图 2 所示:通过对比图 1 和图 2 中的链表不难得知,所谓反转链表,就是将链表整体“反过来”,将头变成尾、尾变成头。
那么,如何实现链表的反转呢?常用的实现方案有4 种,这里分别将它们称为迭代反转法、递归反转法、就地逆置法和头插法。
值得一提的是,递归反转法更适用于反转不带头节点的链表;其它3 种方法既能反转不带头节点的链表,也能反转带头节点的链表。
将以图1 所示,即不带头节点的链表为例,给大家详细讲解各算法的实现思想。
1、迭代反转链表该算法的实现思想非常直接,就是从当前链表的首元节点开始,一直遍历至链表的最后一个节点,这期间会逐个改变所遍历到的节点的指针域,另其指向前一个节点。
具体的实现方法也很简单,借助 3 个指针即可。
以图 1 中建立的链表为例,首先我们定义3 个指针并分别命名为beg、mid、end。
它们的初始指向如图 3 所示:在上图的基础上,遍历链表的过程就等价为:3 个指针每次各向后移动一个节点,直至mid 指向链表中最后一个节点(此时end 为NULL)。
需要注意的是,这 3 个指针每移动之前,都需要做一步操作,即改变 mid 所指节点的指针域,另其指向和 beg 相同。
1)在图 3 的基础上,我们先改变 mid 所指节点的指针域指向,另其和 beg 相同(即改为 NULL),然后再将 3 个指针整体各向后移动一个节点。
整个过程如图 4 所示:2)在图4 基础上,先改变mid 所指节点的指针域指向,另其和beg 相同(指向节点 1 ),再将 3 个指针整体各向后移动一个节点。
整个过程如图 5 所示:3)在图5 基础上,先改变mid 所指节点的指针域指向,另其和beg 相同(指向节点 2 ),再将 3 个指针整体各向后移动一个节点。
整个过程如图 6 所示:4)图 6 中,虽然 mid 指向了原链表最后一个节点,但显然整个反转的操作还差一步,即需要最后修改一次mid 所指节点的指针域指向,另其和beg相同(指向节点 3)。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
倒置单链表的算法
void pur_LinkList(LinkList H)
{ LNode *p,*q,*r;
p=H->next; /*p指向第一个结点*/
if(p==NULL) return;
while (p->next)
{ q=p;
while (q->next) /* 从*p的后继开始找重复结点*/
{ if (q->next->data==p->data)
{ r=q->next; /*找到重复结点,用r指向,删除*r */
q->next=r->next;
free(r);
} /*if*/
else q=q->next;
} /*while(q->next)*/
p=p->next; /*p指向下一个,继续*/
} /*while(p->next)*/
} ―――――――――――――――――――――――――――――――――――――status LinkListReverse(LinkList L) /*对单链表中的元素倒置*/
{ int a[N] ,i=0,count=0;
LinkList Lb;
Node *p,*q;
p=L->next;
while(p!=NULL)
{
a[i++]=p->data;
p=p->next;
count++;
}
――――――――――――――――――――――――――――――――
2.21
void reverse(SqList &A)//顺序表的就地逆置
{
for(i=1,j=A.length;i<j;i++,j--)
A.elem[i]<->A.elem[j];
}//reverse
2.22
void LinkList_reverse(Linklist &L)//链表的就地逆置;为简化算法,假设表长大于2
{
p=L->next;q=p->next;s=q->next;p->next=NULL;
while(s->next)
{
q->next=p;p=q;
q=s;s=s->next; //把L的元素逐个插入新表表头
}
q->next=p;s->next=q;L->next=s;
}//LinkList_reverse
分析:本算法的思想是,逐个地把L的当前元素q插入新的链表头部,p为新表表头.。