单链表就地逆置

题目:有一个线性表(a1,a2,a3,...,an),采用带头节点的单链表L存储,设计一个算法将其就地逆置,线性表变为(an,...a3,a2,a1)。所谓“就地”指辅助存储空间为O(1)。

解题思路:

如果是顺序存储的话,我们很容易想到解题思路,利用1个辅助变量让第1个元素与第n个元素交换,然后再利用这个辅助变量让第2个元素与第n-1个元素交换,...最后利用这个辅助变量让第n/2个元素与第n+1-n/2个元素交换。

如果不要求“就地”的话,可以创建一个n个元素辅助数组,一次访问单链表中的每个元素,并存储到该数组中,然后再依次访问单链表中的每一个元素,同时从该数组的末尾开始为单链表中的元素赋值,直到数组第1个元素的值赋值给单链表最后一个元素。

如果单链表为空或单链表中只有头结点,那么单链表不需要逆置,如果单链表中只有一个元素,逆置之后它的位置还是不会改变,所以可以不逆置。当单链表中有2个或两个以上的元素时,从第1个元素断开,令它的next为空,依次访问第2个元素到第n个元素,当访问到其中的任意一个元素时,将它插入到头结点之后,也就是把它插入到第1个位置,这样原始的第1个元素就会被后面的n-1个元素插入到它的前面,原始的第2个元素就会被后面的n-2个元素插入到它的前面,...直到原始的第n个元素插入到第1个位置。这样就实现了带头结点的单链表的就地逆置。

ADT定义如下

#define ElemType int

typedef struct LNode{

ElemType data;

LNode *next;

}LNode,*LinkList;

算法实现:

void reverse(LinkList &L)
{
    //单链表为空或只有头结点或只有一个元素,不用进行逆置操作
	if(L==NULL||L->next==NULL||L->next->next==NULL) return;

	LNode* p=L->next->next;//令p指向线性表中第2个元素a2
	L->next->next=NULL;//令线性表中第1个元素a1的next为空
	while(p)
	{
		//将p插入到头结点之后
		p->next=L->next;
		L->next=p;

		p=p->next;//继续访问下一个元素
	}
}
时间: 2024-10-07 10:46:04

单链表就地逆置的相关文章

单链表就地逆置(Java版)

题目:有一个线性表(a1,a2,a3,...,an),采用带头节点的单链表L存储,设计一个算法将其就地逆置,线性表变为(an,...a3,a2,a1).所谓"就地"指辅助存储空间为O(1). 解题思路: 如果是顺序存储的话,我们很容易想到解题思路,利用1个辅助变量让第1个元素与第n个元素交换,然后再利用这个辅助变量让第2个元素与第n-1个元素交换,...最后利用这个辅助变量让第n/2个元素与第n+1-n/2个元素交换. 如果不要求"就地"的话,可以创建一个n个元素辅

线性表之顺序表奇偶调整和单链表就地逆置

线性表之顺序表奇偶调整,就是指将顺序表的奇数与偶数位置互换,以最优方法解决,因为方法很多,比如,开辟一个新的顺序表分别存放奇偶数,也可以从头向后寻找奇偶数放置到尾部或头部,但这些都会增大时间与空间的消耗.最优法则是前后分别寻找奇偶不同类型数,满足前奇后偶(或前偶后期),交换两数位置,实现时间复杂度O(n),空间O(1)的方案. void AdjustSqlist(SeqList *L) { int i=0,j=L->last; int temp; while(i<j) { while(L-&g

【数据结构课程作业】单链表就地逆置

#include <stdio.h> #include <stdlib.h> typedef struct List { int val; struct List *next; }List; void InitList(List **h, List **t) { *h = (List *)malloc(sizeof(List));//*h就是头指针的地址 *t = (List *)malloc(sizeof(List));//*t就是尾指针的地址 if(!(*h) || !(*t)

数据结构与算法-链表就地逆置

链表操作,单链表就地逆置 void Inverse(LinkList &L) { LNode *p, *q; p = L->next; /*记录第一个结点地址*/ L->next = NULL; /*把链表设置成空表*/ while (p != NULL) /*依次按头插法将各结点插入,就实现了逆置*/ { q = p; /*用q记录待插入结点地址*/ p = p->next; /*用p记录待插入结点的后继结点地址*/*/ q->next = L->next; /*将

(转)单链表的逆置

对于单链表的逆置有两种方法可以实现: (1)利用辅助指针 基本思想:在遍历结点过程中,设置辅助指针,用于记录先前遍历的结点.这样依次编译的过程中只需修改其后继结点的next域即可. 实现代码: 1 typedef int DataType; //类型定义 2 typedef struct node{ //单链表定义 3 DataType data; 4 struct node* next; 5 }LinkedNode,*LinkList; 6 void ReverseList(LinkList&

单链表的逆置--普通循环方法(详细图解)

关于单链表的逆置,大家都很清楚有两种基本方法:(1)普通的循环的方法.(2)递归调用方法.今天正好研究这两种方法,发现很不理解代码这么写的具体的作用,诚如很多人所说,吃透这个还是要自己画一个详细的过程图.今天就给大家介绍一下(普通的循环方法)我学习下来的一些经验,如有不对之处还望大家一起交流. 首先,以下是关于单链表逆置的普通循环方法的代码: //单链表定义 typedef struct ListNode{ int m_nValue; ListNode* pNext; }; //单链表逆置实现

C语言:【单链表】逆置反转单链表

#include<stdio.h> #include<assert.h> #include<stdlib.h> typedef int DataType; typedef struct SListNode {     DataType data;     struct SListNode* next; }SListNode; SListNode* BuyNode(DataType x) {     SListNode* next = (SListNode*)malloc

单链表的逆置(不带头结点)

#include <stdio.h> #include <stdlib.h> typedef struct node { int data; struct node *next; }Node; Node *Initiate(Node *linklist) { linklist=NULL; return linklist; } Node* creatlist_end(Node *linklist)//尾插法 { int i,n; Node *p,*q; scanf("%d&

数据结构c语言中单链表就地逆置问题

法一: list_node *list_reverse(list_node *head) { list_node *p = head->next; list_node *q = NULL; head->next = NULL; while(p != NULL) { q = p->next;          /*保存下一个节点*/ p->next = head->next; /*把节点插入到头结点后面*/ head->next = p;       /*头结点一直指向最