首页 > 其他分享 >单链表建表,倒置,遍历(不使用Class,简洁易懂)

单链表建表,倒置,遍历(不使用Class,简洁易懂)

时间:2023-11-21 20:13:34浏览次数:34  
标签:node head 遍历 ListNode 表建表 next now NULL Class

在C++中通过递归方法实现单链表倒置

初始化列表

struct ListNode{
	int val;
	LiseNode* next;
	ListNode(int x) :val(x),next(NULL){}
};

遍历

void query_node(){
	node *p=head;
	while(p!=NULL){
		cout<<p->data<<' ';
		p=p->nxt;
	}
	cout<<endl;
}

建表(尾部插入)

void build_node(){
	head=NULL,tail=NULL;
	for(int i=1;i<=5;i++){
		int x;
		cin>>x;
		node *tmp=new node(x);
		if(head==NULL) head=tail=tmp;
		else {
			tail->nxt=tmp;
			tail=tmp;
		}
	} 
}

倒置(递归)

图解

好的,以下是这部分代码的图解:

假设原始链表为:1 -> 2 -> 3 -> 4 -> NULL

  1. reverseList(1) 调用
    • head = 1, head->next = 2
    • 递归调用 reverseList(2),返回倒置后的头结点 newHead = 4
  2. reverseList(2) 调用
    • head = 2, head->next = 3
    • 递归调用 reverseList(3),返回倒置后的头结点 newHead = 4
  3. reverseList(3) 调用
    • head = 3, head->next = 4
    • 递归调用 reverseList(4),返回倒置后的头结点 newHead = 4
  4. reverseList(4) 调用
    • head = 4, head->next = NULL
    • 返回 head 作为倒置后的头结点
  5. 回到 reverseList(3)
    • 将 head->next->next = head,即 4 -> 3
    • 将 head->next = NULL,即 3 -> NULL
    • 返回 newHead = 4 作为倒置后的头结点
  6. 回到 reverseList(2)
    • 将 head->next->next = head,即 3 -> 2
    • 将 head->next = NULL,即 2 -> NULL
    • 返回 newHead = 4 作为倒置后的头结点
  7. 回到 reverseList(1)
    • 将 head->next->next = head,即 2 -> 1
    • 将 head->next = NULL,即 1 -> NULL
    • 返回 newHead = 4 作为倒置后的头结点
  8. 完成递归调用,返回倒置后的链表头结点 newHead = 4

因此,最终倒置后的链表为:4 -> 3 -> 2 -> 1 -> NULL

node *reverse_node(node *now){
	if(now->nxt==NULL) return now;
	node *newhead=reverse_node(now->nxt);
	now->nxt->nxt=now;
	now->nxt=NULL;
	return newhead;
}

完整代码

1.精简版

#include<bits/stdc++.h>
using namespace std;
struct node{
	int data;
	node *nxt;
	node(int x) : data(x),nxt(NULL){}
}; 
node *head,*tail;
void query_node(){
	node *p=head;
	while(p!=NULL){
		cout<<p->data<<' ';
		p=p->nxt;
	}
	cout<<endl;
}
void build_node(){
	head=NULL,tail=NULL;
	for(int i=1;i<=5;i++){
		int x;
		cin>>x;
		node *tmp=new node(x);
		if(head==NULL) head=tail=tmp;
		else {
			tail->nxt=tmp;
			tail=tmp;
		}
	} 
}
node *reverse_node(node *now){
	if(now->nxt==NULL) return now;
	node *newhead=reverse_node(now->nxt);
	now->nxt->nxt=now;
	now->nxt=NULL;
	return newhead;
}
int main(){
	build_node();
	cout<<"original node:";
	query_node();
	head=reverse_node(head); //注意要把head指向新的首节点 
	cout<<"After reverse:";
	query_node();
	return 0;
}

2.详细注释版

#include <iostream>
using namespace std;

// 定义链表结点
struct ListNode {
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(NULL) {} 
};


// 递归函数,实现链表倒置
ListNode* reverseList(ListNode* head) {
    // 如果链表为空或者只有一个结点,则直接返回
    if (head->next == NULL) {
        return head;
    }

    // 递归调用,获取倒置后的链表头结点
    ListNode* newHead = reverseList(head->next);

    // 将当前结点插入到倒置后链表的末尾
    head->next->next = head;
    head->next = NULL;

    return newHead;
}

// 初始化链表,从键盘输入五个数据依次插入链表尾部
ListNode* initList() {
    ListNode* head = NULL;
    ListNode* tail = NULL;
    for (int i = 0; i < 5; i++) {
        int x;
        cin >> x;
        ListNode* node = new ListNode(x); //这里必须使用new 
        if (head == NULL) {
            head = node;
            tail = node;
        }
        else {
            tail->next = node;
            tail = node;
        }
    }
    return head;
}

int main() {
    // 初始化链表
    ListNode* head = initList();

    // 输出原始链表
    cout << "Original List: ";
    ListNode* p = head;
    while (p) {
        cout << p->val << " ";
        p = p->next;
    }
    cout << endl;

    // 倒置链表
    head = reverseList(head);

    // 输出倒置后的链表
    cout << "Reversed List: ";
    p = head;
    while (p) {
        cout << p->val << " ";
        p = p->next;
    }
    cout << endl;

    return 0;
}

标签:node,head,遍历,ListNode,表建表,next,now,NULL,Class
From: https://www.cnblogs.com/conprour/p/17847445.html

相关文章

  • 8.3 Windows驱动开发:内核遍历文件或目录
    在笔者前一篇文章《内核文件读写系列函数》简单的介绍了内核中如何对文件进行基本的读写操作,本章我们将实现内核下遍历文件或目录这一功能,该功能的实现需要依赖于ZwQueryDirectoryFile这个内核API函数来实现,该函数可返回给定文件句柄指定的目录中文件的各种信息,此类信息会保存在PF......
  • Class成员函数的声明方式
    1#include<iostream>usingnamespacestd;classComplex{ doublereal,imag; public: Complex(doubler=0,doublei=0):real(r),imag(i){}; operatordouble()const;//强制类型转换};Complex::operatordouble()const{returnreal;}intmai......
  • 三种办法遍历对象数组,获取数组对象中所有的属性值(key,value);四种方法查找对象数组里面
    一,获取对象数组中某属性的所有值如果是要获取具体第几个属性的值,倒是可以用arr[i].name的方法来实现。若是全部的属性的值,并返回一个新的数组嘞,思路是加循环遍历方法如下。1、from方法vararr=[{id:1,name:"小明"},{id:2......
  • 数据结构之二叉树的遍历3(java)
    一:概述绝大多数的可以用递归解决问题,也可以使用另一种数据结构来解决,这种数据结构就是栈。因为递归和栈都有回溯的特性。二:具体说明如何借助栈来实现二叉树的遍历,下面以二叉树的前序遍历为例,来阐述具体过程。<1>首先遍历二叉树的根节点1,放入栈中。<2>遍历根节点1的左孩子节点2,放入......
  • 遍历循环,只要有其中一个符合就退出
    使用stream流的anyMatch判断的条件里,任意一个元素成功,返回true上代码List<SectorInfo>sectorsInfo=scanResultParser.apply(scanResult);returnsectorsInfo.stream().map(sectorInfo->badSectorCountParser.apply(sectorInfo.getValue()))......
  • vue3_Extraneous non-props attributes (class) were passed to component but could
    今天的开发中发现了这个问题Extraneousnon-propsattributes(class)werepassedtocomponentbutcouldnotbeautomaticallyinheritedbecausecomponentrendersfragmentortextrootnodes.原因:是因为vue3中允许在<template>中不设置根节点,所以我在某个页面中......
  • 无涯教程-Ruby Class Case Study函数
    对于您的案Example研究,您将创建一个名为Customer的Ruby类,并将声明两个方法-display_details-此方法将显示客户的详细信息。total_no_of_customers-此方法将显示在系统中创建的客户总数。#!/usr/bin/rubyclassCustomer@@no_of_customers=0definitiali......
  • JVM深入学习-ClassLoader篇(一)
    初识JVM---ClassLoader深入理解ClassLoader、SPI机制Class对象的理解java在诞生之初,就有一次编译到处运行的名言,今天我们来探究一下,从java代码到class到运行,JVM中的ClassLoader充当一个什么样的角色。一个简单的JVM流程图(简单了解)流程图.jpg从位置角度理解JVM:就JVM在......
  • 遍历List移除元素时踩坑点
    1、问题描述在遍历List并在循环体中移除元素时需要注意以下几点移除元素后数据总量会越来越小,可能造成数组下标越界移除元素后,每个元素原有位置也会发生改变,需确认移除的元素是否是真正需要移除的由于删除元素后,每个元素位置前移,会有部分数据直接跳过循环例如数组中有......
  • 图的建立与深度、广度遍历
    图的建立有两种方式,一种是邻接矩阵,也就是顺序存储。另一种则是邻接表在遍历过程中我们需要有一个数组,用来标记结点是否被调用过,我们称它为visited数组。我们需要初始化一个二维矩阵edge[i][j],用来存储边的集合,含义为第i个结点与第j个结点之间有边。其次我们在创建一个存储......