首页 > 其他分享 >链表 Linked List

链表 Linked List

时间:2024-03-17 17:24:34浏览次数:22  
标签:Node head ite List next 链表 num Linked

2024.3.15
芝士wa
参考视频:bilibli-数据结构-链表
“印度小哥讲得真好”


链表

  • 对于链表来说,存储数据需要两个部分,一是数据本身,二是指针,该指针指向下一个数据的地址,依次链接,直到最后一个元素,指针指向空(NULL)

单向链表结构

  • 遍历的时间复杂度为O(n)

  • 插入的时间复杂度为O(n)

  • 删除的时间复杂度为O(n)


链表VS数组

  • 数组是连续存储空间,链表通过指针维系,存储数据并不连续

  • 数组可以通过下标访问元素,只需要O(1)的时间复杂度,而链表则必须按照顺序访问,因此时间复杂度为O(n/2) = O(n)

  • 数组的大小是固定的,在创建数组时确认

  • 优势:链表在添加或删除元素时,避免了不相关元素的复制移动,空间复杂度较小

  • 使用链表时,要格外注意指针问题


链表的C++实现

完整代码
#pragma once
#include <iostream>
using namespace std;


template<class T>
class Node
{
public:
	T data;
	Node* next;
};

template<class T>
class LinkedList
{
public:
	LinkedList();
	~LinkedList();
	Node<T>* head;
	
	int m_num;//记录节点个数
	//尾插法
	void Insert(T x);

	//在特定位置添加
	void Insert(T x, int n);

	//打印,遍历法
	void print();

	//递归方法打印
	void Rprint(Node<T>* p);

	//特定位置删除
	void remove(int n);

	//反转链表,迭代法
	void reverse();

	//反转链表,递归方法
	void Reverse(Node<T>* p);
};

template<class T>
LinkedList<T>::LinkedList()
{
	head = new Node<T>;
	head->next = NULL;
	this->m_num = 0;
}


template<class T>
LinkedList<T>::~LinkedList()
{
	Node<T>* ite = head;
	Node<T>* next;
	while (ite != NULL) {
		next = ite->next;
		delete ite;
		ite = next;
	}
	this->m_num = 0;
}




template<class T>//尾插法添加元素
void LinkedList<T>::Insert(T x)
{
	Node<T>* end = new Node<T>;
	end->data = x;
	end->next = NULL;

	if (head== NULL) {
		//链表为空
		head = end;

		this->m_num++;
		cout << "添加成功,当前节点数量:" << this->m_num << endl;
	}
	else {
		Node<T>* ite = head;
		//链表不为空,得到末尾end
		while (ite->next != NULL) {
			ite = ite->next;
		}
		//现在ite指向最后一个元素
		ite->next = end;
	}
	this->m_num++;
	cout << "添加成功,当前节点数量:" << this->m_num << endl;
}


template<class T>//特定位置添加元素
void LinkedList<T>::Insert(T x, int n)
{
	Node<T>* temp = new Node<T>;
	temp->data = x;
	temp->next = NULL;
	if (n == 1) {
		//在头节点之后添加
		temp->next = head->next;
		head = temp;

		this->m_num++;
		cout << "添加成功,当前节点数量:" << this->m_num << endl;
		return;
	}
	else if(n > 1 && n <= this->m_num){
		Node<T>* ite = head;
		//找到第n-1个元素,
		for (int i = 0; i <= n - 2; i++) {
			ite = ite->next;
		}
		temp->next = ite->next;
		ite->next = temp;
		this->m_num++;
		cout << "添加成功,当前节点数量:" << this->m_num << endl;
		return;
	}
	else {
		cout << "越界" << endl;
		return;
	}
}

template<class T>
void LinkedList<T>::print()
{
	Node<T>* ite = head;
	while (ite!= NULL) {
		cout << ite->data << "\t";
		ite = ite->next;
	}
	cout << endl;
}
template<class T>
void LinkedList<T>::Rprint(Node<T> * p)
{
	if (p == NULL) {
		return;
	}
	Rprint(p->next);
	cout << p->data << "\t";
}

template<class T>
void LinkedList<T>::remove(int n)
{
	Node<T>* temp = head;
	//第一个节点
	if (n == 1) {
		head = head->next;
		delete temp;

		this->m_num--;
		cout << "删除成功,当前节点数量:" << this->m_num << endl;
		return;
	}
	//第2~num之间删除节点
	else if (n > 1 && n <= this->m_num) {
		for (int i = 0; i < n - 2; i++) {
			temp = temp->next;
		}
	
		//现在temp指向的是第n-1个节点
		Node<T>* temp1 = temp->next;//指向第n个
		temp->next = temp1->next;
		delete temp1;

		this->m_num--;
		cout << "删除成功,当前节点数量:" << this->m_num << endl;
		return;
	}
	else {
		cout << "越界" << endl;
		return;
	}
	
}

template<class T>
void LinkedList<T>::reverse()
{
	Node<T>* current, * prev, * next;
	current = head;
	prev = NULL;
	while (current != NULL) {
		next = current->next;
		current->next = prev;
		prev = current;
		current = next;
	}
	head = prev;
}

template<class T>
void LinkedList<T>::Reverse(Node<T>* p)
{
	if (p->next == NULL) {
		head = p;
		return;
	}
	Reverse(p->next);
	p->next->next = p;
	p->next = NULL;
}

  • 模板,泛型
  • 内部维护链表长度
  • 分别用递归和迭代的方式实现了打印和反转
  • 进行了简单的越界判断处理




双向链表

双向链表

template<class T>
class Node
{
  T data;
  Node* prev;
  Node* next;
};

总结

本文介绍了链表的概念和特性,并用C++实现了单链表。

标签:Node,head,ite,List,next,链表,num,Linked
From: https://www.cnblogs.com/cheese-wa/p/18076041

相关文章

  • 5.合并两个有序链表
    链表合并B站左程云讲解连接链表结构publicstaticclassListNode{publicintval;publicListNodenext;publicListNode(intval){this.val=val;}publicListNode(intval,ListNodenext){......
  • 数据结构ArrayList之杨辉三角庖丁解牛!
    题外话先给大家露一手我对杨辉三角的理解,虽说标题是庖丁解牛,但是还是虚心请教一下大家,有什么意见都可以提出!正题思维逻辑先画个杨辉三角,有几点需要大家注意一下1.杨辉三角其实在代码里就是一个二维数组,图中i代表行但是是从0开始的,而j则代表每行的元素2.如果想......
  • 数据结构之LinkedList底层代码全方位细节实现!
    题外话我很想发点nb的知识,但是路得一步一步走,饭也得一点一点吃,所以说不积跬步无以至千里,不积小流无以成江海!!!大家一起努力,未来属于我们!!正题理解链表相信大家看到这都应该明白链表,那就简单讲下链表组成今天实现LinkedList底层,LinkedList是一个双向链表,但是咱......
  • Winform编程详解十:ListBox 列表框
     一、属性介绍    1.(Name)           控件的对象标识符ID    2.Items        控件的数据集合    3.BackColor        控件的背景颜色    4.BorderStyle     ......
  • leetcode 21 合并两个有序链表
    https://www.bilibili.com/video/BV1xa411A76q?p=4&vd_source=cdfcf738e0429ec2cffe4778dd8dd0e4 #迭代#https://blog.csdn.net/m0_61661179/article/details/127205244classSolution:defmergeTwoLists(self,list1:Optional[ListNode],list2:Optional[List......
  • HarmonyOS 与 ArkTS | ForEach 循环渲染 + List 实现滑动视频列表
    HarmonyOS与ArkTS|ForEach循环渲染+List实现滑动视频列表本文为记录,内容较简单,无注释。实现效果:代码:importimagefrom'@ohos.multimedia.image'classItem{name:stringclassification:stringimage:ResourceStrconstructor(name:string,classi......
  • 数据结构(二)双链表---以题为例
    实现一个双链表,双链表初始为空,支持 5 种操作:在最左侧插入一个数;在最右侧插入一个数;将第 k 个插入的数删除;在第 k 个插入的数左侧插入一个数;在第 k 个插入的数右侧插入一个数现在要对该链表进行 M 次操作,进行完所有操作后,从左到右输出整个链表。注意:题目中第 ......
  • 【Java】List, Set, Queue, Map 区别?
    目录List,Set,Queue,Map区别?Collection和CollectionsListArrayList和Array区别?ArrayList与LinkedList区别?ArrayList能添加null吗?ArrayList插入和删除时间复杂度?LinkedList插入和删除时间复杂度?LinkedList为什么不能实现RandomAccess接口?SetComparabl......
  • java集合框架——List集合概述及ArrayList,LinkedList的区别
    前言:List系列集合是Collection集合中两个系列的其中一个,整理下笔记。打好基础,daydayup!需要了解Collection的,可以看这篇java集合框架——Collection集合概述  List系列集合List系列集合的特点为添加的元素有序,可重复,有索引。在继承了Collection方法的基础上,有很多索引......
  • 滴水逆向笔记系列-c++总结4-41.new-delete-vector-42.链表
    第四十课c++8new-delete-vector1.内存空间复习在类外函数外的变量就是全局变量,程序一编译地址就已经确定了的临时数据,参数和局部变量就是在堆栈里而使用malloc函数动态申请的则是在堆里2.跟踪调试反汇编函数我们调用malloc函数申请内存,但是不是malloc一个函数完成整个......