首页 > 其他分享 >大一计算机的自学总结:单双链表的反转

大一计算机的自学总结:单双链表的反转

时间:2025-01-05 15:32:02浏览次数:3  
标签:head list next tail 大一 双链 listD 自学 NULL

前言

为了减少单个文件里的代码量(懒),于是将能用到的函数都写进一个.h文件里了。

其中大部分函数都在我“初见链表”的文章里写过了。

#include<bits/stdc++.h>

using namespace std;

typedef struct node
{
	int value;
	struct node* next;
}Node;

typedef struct nodeD
{
	int value;
	struct nodeD* last;
	struct nodeD* next;
}NodeD;

typedef struct
{
	Node* head;
	Node* tail;
}List;

typedef struct
{
	NodeD* head;
	NodeD* tail;
}ListD;

//添加链表
void add(List &list,int n)
{
	Node* p=(Node*)malloc(sizeof(Node));
	p->value=n;
	p->next=NULL;
	
	if(list.tail==NULL)
	{
		list.head=p;
		list.tail=list.head; 
	}
	else
	{
		list.tail->next=p;
		list.tail=list.tail->next;
	}
} 

//添加双链表 
void addD(ListD &listD,int n)
{
	NodeD* p=(NodeD*)malloc(sizeof(NodeD));
	p->value=n;
	p->last=p->next=NULL;
	
	if(listD.tail==NULL)
	{
		listD.head=p;
		listD.tail=listD.head;
	}
	else
	{
		p->last=listD.tail;
		listD.tail->next=p;
		listD.tail=listD.tail->next;
	}
}

//打印链表
void printList(List List)
{
	for(Node* p=List.head;p!=NULL;p=p->next)
	{
		cout<<p->value<<" ";
	}
	cout<<endl;
} 

//打印双链表
void printListD(ListD ListD)
{
	int a;
	cout<<"From head or tail?  "<<"head:0  tail:1"<<endl;
	cin>>a;
	
	if(a==0)
	{
		for(NodeD* p=ListD.head;p!=NULL;p=p->next)
		{
			cout<<p->value<<" ";
		}	
	}
	else if(a==1)
	{
		for(NodeD* p=ListD.tail;p!=NULL;p=p->last)
		{
			cout<<p->value<<" ";
		}
	}
	else
	{
		cout<<"Seriously?";
	}
	cout<<endl;
} 

//清除链表
void freeList(List &list)
{
	Node* q;
	for(Node* p=list.head;p!=NULL;p=q)
	{
		q=p->next;
		free(p);
	}
} 

//清除双链表
void freeListD(ListD &listD)
{
	NodeD* q;
	for(NodeD* p=listD.head;p!=NULL;p=q)
	{
		q=p->next;
		free(p);
	}
} 

一、双链表

#include<bits/stdc++.h>
#include"LinkedListFunction.h"
using namespace std;

int main()
{
	ListD list;
	list.head=list.tail=NULL;
	
	int n;
	cout<<"Add n to double list:"<<endl;
    do
    {
    	cout<<"n:";
        cin>>n;
        if (n != -1)
        {
            addD(list, n);
        }
    } while (n != -1);
    
    printListD(list);
	
	freeListD(list);
	return 0;
}

 双链表因为其双向连接的特性,反转输出只需选择从head开始还是从tail开始即可。

二、单链表反转

#include<bits/stdc++.h>
#include"LinkedListFunction.h"

using namespace std;

//反转链表
void Reverse(List &list)
{
	Node* lastNode=NULL;
	Node* nextNode=NULL;
	Node* t=list.head;    
	while(list.head!=list.tail)
	{
		nextNode=list.head->next;
		list.head->next=lastNode;
		lastNode=list.head;
		list.head=nextNode;
	}
	list.head->next=lastNode;
	list.tail=t;
} 

int main()
{
	List list;
	list.head=list.tail=NULL;
	
	int n;
	cout<<"Add n to list:"<<endl;
    do
    {
    	cout<<"n:";
        cin>>n;
        if (n != -1)
        {
            add(list, n);
        }
    } while (n != -1);

	cout<<"Before reverse:"<<endl;
	printList(list);
	
	Reverse(list);
	
	cout<<"After reverse:"<<endl;
	printList(list);
	
	freeList(list);
	return 0;
} 

单链表的反转就复杂得多了。反转一个单链表,不仅要将head和tail的位置互换,还要让原本指向下一个结点的next指向上一个结点。为了实现这两点,需要设置一个指向上一个结点的指针lastNode和指向下一个结点的指针nextNode。

首先,先初始化两个指针为NULL,然后先用t保存head,方便最后和tail交换。之后进入循环,即当head没有移动到tail的位置,循环继续。

循环中,为了改变每个结点next的指向,就要用到lastNode和nextNode两个指针,利用head指针,先让nextNode移动到head的下一个结点,再让head所指结点的next指针指向上一个结点,然后将lastNode移动到head的位置,最后将head移动到nextNode的位置。

跳出循环后,即head移动到了tail的位置,此时需要注意,head(tail)所指结点的next还没有被改变,即仍然指向NULL,所以需要让此时head所指结点的next指向lastNode,最后让tail去到最初head的位置即可。

总结

相比双链表,单链表的反转复杂得多,重点是反转时借助的lastNode和nextNode两个指针。

END

标签:head,list,next,tail,大一,双链,listD,自学,NULL
From: https://blog.csdn.net/2402_89326161/article/details/144933165

相关文章

  • 自学资料 - LoRA - 低秩微调技术
    目录1.微调分类2.LoRA算法全称:Low-RankAdaptation微调的不同类别1.微调分类微调主要分为三类:一种是全参数的微调(类别1)。缺点,如果利用一些较好的优化算法,梯度更新和之前所有的梯度(有历史记忆)都有关啥的会导致占用较多的显存。一种是部分参数微调(可......
  • 自学资料 - Dalle2模型 - 文生图技术
    Dalle2模型-论文中为unCliP目录Dalle2模型-论文中为unCliP1.Dalle2的引言2.GAN模型优缺点优点缺点3.AE和DAE(denoisingAE)原理共同点4.VAE(变分自编码器)优点5.VQVAE(向量自编码器)原理优点6.Dalle模型原理7.Diffusion模型模型更新过程优点缺点:8.Dalle2......
  • 大一计算机的自学总结:二分搜索
    前言回顾之前初学循环时写过的猜数小游戏,若范围是0~100,大多数人的猜法都是先猜50,若大了,则猜25;若小了,则猜75......这种搜索方法,就是二分搜索。一、二分搜索原理二分搜索的原理很简单,但非常实用。二分搜索时,每次都把有序数组分成两份,判断中点位置的值和要搜索的值的大小关系,然......
  • 什么是数据运营(自学记录)
    1.总结跟普通运营一样都是产品和用户之间的枢纽,不过更偏向于对数据进行分析。2.干什么的运用数据来指导决策、实现业务增长。侧重支持业务决策、互联网运营等类别。根据维度的不同对用户进行层级划分。具体:1.AARRR(具体内容大家可以看AARRR模型最详解-知乎)用户获取(Ac......
  • 网络安全(黑客)自学
    ......
  • 有很多同学问快到期末了怎么办?人工智能本科大一该怎么过?
    大家好,我是天海。过完了人工智能本科四年的“摸着石头过河”的大学生活,我的这些经验希望能够帮到你。我将推荐一些大学期间的打怪升级的成长路线供大家参考。大一:学习好基础课拿绩点、学习一些编程语言、可以适当参加社团、学生会。1、大一上学期在刚入学后,学校是会有一场......
  • 《DNK210使用指南 -CanMV版 V1.0》第四十八章 自学习分类实验
    第四十八章自学习分类实验1)实验平台:正点原子DNK210开发板2)章节摘自【正点原子】DNK210使用指南-CanMV版V1.03)购买链接:https://detail.tmall.com/item.htm?&id=7828013987504)全套实验源码+手册+视频下载地址:http://www.openedv.com/docs/boards/k210/ATK-DNK210.html5)正点......
  • 【Rust自学】9.2. Result枚举与可恢复的错误 Pt.1:match、expect和unwrap处理错误
    喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)9.2.1.Result枚举通常情况下,错误都没有严重到需要停止整个程序的地步。某个函数之所以运行失败或者是遇到错误通常是由一些可以简单解释并做出响应的原因引起的。比......
  • 袁町招教---从12月开始备考语文教师编攻略计划(自学版)
    语文学科一直都是教师编考试里数一数二的卷,想要上岸还真是不容易。去年我能以高分上岸我们市区语文教师编也是努力了很久的,下面给大家分享我的备考经验,希望能帮到你们顺利一战上岸!!-......
  • 零基础自学黑客渗透网络安全必备知识(详细版),啃完这些足够了
    怎么入门?这个Web安全学习路线,整体大概半年左右,具体视每个人的情况而定。(上传一直很模糊,所以就没有展开了,需要高清版的可以在下面领取)如果你把每周要学的内容精细化到这种程度,你还会担心学不会,入不了门吗,其实说到底就是学了两个月,但都是东学一下,西学一下,什么内容都是浅尝......