iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++ 实现单链表创建、插入和删除
  • 932
分享到

C++ 实现单链表创建、插入和删除

2024-04-02 19:04:59 932人浏览 泡泡鱼
摘要

目录c++单链表创建、插入和删除1.头节点插入和删除结果2.中间节点插入和删除结果3.尾结点插入和删除结果C++单链表(带头结点)总结归纳代码实现C++单链表创建、插入和删除 这里仅

C++单链表创建、插入和删除

这里仅提供一种思路。

#include <iOStream>
#include <stdio.h>
#include <string>
#include <coNIO.h>
 

 

 
using namespace std;
 
struct node
{
	int data;
	node *next;
};
typedef struct node node, *list;
 
// 创建单链表
node *creat()
{
	node *head, *p;
	head = new node;
	p = head;
 
	int x, cycle = 1;
	while (cycle)
	{
		cout << "Please input the data for single linker : ";
		cin >> x;
 
		if (x != 0)
		{
			node *s = new node;
			s->data = x;
			cout << "Input data : " << x << endl;
 
			p->next = s;
			p = s;
		}
		else
		{
			cycle = 0;
			cout << "Input done! " << endl;
		}
	}
 
	head = head->next;
	p->next = NULL;
	//cout << "\nFirst data of single linker is " << head->data << endl;
 
	return head;
}
 
// 单链表测长
int length(node *head)
{
	int n = 0;
	node *p = head;
 
	while (p != NULL)
	{
		p = p->next;
		n++;
	}
 
	return n;
}
 
// 单链表打印
void printL(node *head)
{
	node *p = head;
 
	while (p != NULL)
	{
		cout << "Single Linker data is " << p->data << endl;
		p = p->next;
	}
}
 
// 单链表插入
node *insert(node *head, int num)
{
	node *p0, *p1, *p2;
	p1 = head;
 
	p2 = new node;
	p0 = new node; // 插入节点
	p0->data = num;// 插入数据
 
	while (p0->data > p1->data && p1->next != NULL)
	{
		p2 = p1;
		p1 = p1->next;// p0,p1和p2位置: p2->p1->p0
	}
 
	if (p0->data <= p1->data)
	{
		if (p1 == head)
		{// 头部前段插入 p0和p1位置: p0->p1->...
			head = p0;
			p0->next = p1;
		}
		else
		{// 插入中间节点 p0,p1和p2位置: p2-> p0 -> p1
			p2->next = p0;
			p0->next = p1;
		}
	}
	else
	{   // 尾部插入节点 p0,p1和p2位置: p2->p1->p0->NULL
		p1->next = p0;
		p0->next = NULL;
	}
	return head;
}
 
// 单链表删除
node *del(node *head, int num)
{
	node *p1, *p2;
	p2 = new node;
	p1 = head;
 
	while (num != p1->data && p1->next != NULL)
	{
		p2 = p1;
		p1 = p1->next;// p1和p2位置: p2->p1		
	}
 
	if (num == p1->data)
	{
		if (p1 == head)// 删除头节点
		{
			head = p1->next;
			delete p1;
		}
		else
		{
			p2->next = p1->next;
			delete p1;
		}
	}
	else
	{
		cout << num << " could not been found in the current single linker!" << endl;
	}
	return head;
}
 
//=============插入排序====================
node *insertSort( node *head )
{
	node  *p1, *prep1, *p2, *prep2, *temp;
	prep1 = head->next;
	p1 = prep1->next;
	//prep1和p1是否需要手动后移
	bool flag;
 
	while (p1 != NULL)
	{
		flag = true;
		temp = p1;
		//由于是单向链表,所以只能从头部开始检索
		for (prep2 = head, p2 = head->next; p2 != p1; prep2 = prep2->next, p2 = p2->next)
		{
			//发现第一个较大值
			if (p2->data > p1->data)
			{
				p1 = p1->next;
				prep1->next = p1;
				prep2->next = temp;
				temp->next = p2;
				flag = false;
				break;
			}
		}
		//手动后移prep1和p1
		if (flag)
		{
			prep1 = prep1->next;
			p1 = p1->next;
		}
	}
	return head;
}
 
int main()
{
	cout << "***创建单链表***" << endl;
	node *head = creat();
	cout << endl;
 
	cout << "***计算链表长***" << endl;
	int n = length(head);
	cout << "The length of input single linker is " << n << "." << endl;
	cout << endl;
 
	cout << "***打印单链表***" << endl;
	printL(head);
	cout << endl;
 
	cout << "****插入节点****" << endl;
	cout << "Please input the data for inserting operate : ";
	int inData;
	cin >> inData;
	head = insert(head, inData);
	printL(head);
	cout << endl;
 
	cout << "****删除节点****" << endl;
	cout << "Please input the data for deleting operate : ";
	int outData;
	cin >> outData;
	head = del(head, outData);
	printL(head);
	cout << endl;
 
	cout << "****进行排序****" << endl;
	//第一位地址可以存放指示器,从第二位开始保存数据
	node *mylist = new node[sizeof(node)];
	mylist->data = 0;
	mylist->next = NULL;
 
	int len = length(head);
	int i = 0;
	node * cur = mylist;
 
 
	node *headcopy = head;
	while (len--)
	{
		//node * newNode = (node *)malloc(sizeof(node));   
		node *newNode = new node[sizeof(node)];            
		newNode->data = headcopy->data;
		newNode->next = NULL;
		cur->next = newNode;
		cur = cur->next;
		headcopy=headcopy->next;
	}
	head = insertSort(mylist);
	head = del(head, 0);
	printL(head);
 
	return 0;
}

1.头节点插入和删除结果

2.中间节点插入和删除结果

3.尾结点插入和删除结果

C++单链表(带头结点)

总结归纳

  • 头结点可以没有,头指针必须有。访问整个链表,是用过遍历头指针来进行的。
  • 这里没有特别的设置一个头指针,因为当指针指向整个链表 L 时,该指针的实现效果就是头指针。
  • 关于函数中引用的问题,实际上对于带头结点的绝大部分操作,是不需要引用的,因为对于链表的任何操作,传入的实际上都是头指针(头结点),通过头指针的遍历访问后继结点。所以,无论是插入删除还是修改,都不涉及头指针的改变。但如果是不带头指针的单链表操作,就需要添加引用,因为当插入或删除第一个位置的元素时,会涉及头指针的修改,此时的头指针就是链表的第一个元素。
  • 不带头结点的单链表,即单链表的第一个结点就存储数据,头指针也指向第一个结点;带头结点的单链表,第一个结点是头结点,不存储数据,从头结点的 next 开始存储,头指针可以从头结点的 next 开始遍历。
  • 对于结点的前插操作,找到对应位置的结点,设新结点为该节点的后继结点,将该结点的 data 后移至新结点的 data,以此来模拟结点的后移,并且时间复杂度为 O(1),我愿称之为“偷天换日”。
  • 如果采用尾插法创建单链表,可以设置一个尾指针,指向单链表末尾,这样就不用每次都通过遍历找到最后一个结点,但每插入一个都要更新尾指针。这样的时间复杂度为O(1)。
  • 在 DeleteNode 函数中(删除指定结点),存在一处 bug ,当删除结点为最后一个结点时,由于该结点没有后继结点,该函数会报错,初步认为只能通过 DeleteNextLNode函数(删除p结点的后继结点)来实现删除最后一个结点的操作。
  • 大多数情况下,单链表的查询、插入、删除的平均时间复杂度都是O(n),因为要遍历头结点开始查找。但如果对指定结点进行插入和删除,则时间复杂度为O(1),因为不需要再通过遍历找到指定的结点。要具体分析。
  • 如果不带头结点的单链表,则对表头的操作(插入和删除)要特殊处理,例如 List_HeadInsert(头插法创建单链表)、ListInsert(按位序插入)。每次插入后都要更新头指针,而对于带头结点的单链表,它的头指针指向永远是头结点,只需要修改头结点的后继就可以完成插入。

代码实现

#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
// 单链表结点
struct LNode {
    int data;    // 数据域
    LNode *next; // 指针域
};
typedef LNode LNode;     // LNode表示单链表的一个结点
typedef LNode *LinkList; // LinkList表示一个单链表
// 初始化单链表
void InitList(LinkList &L) {
    L = new LNode;
    // L = (LNode *)malloc(sizeof(LNode));
    L->next = NULL;
}
// 判断单链表是否为空
bool Empty(LinkList &L) {
    if (L->next == NULL) {
        return true;
    } else {
        return false;
    }
}
// 获取单链表长度
int GetLength(LinkList &L) {
    LNode *p = L->next;
    int length = 0;
    while (p != NULL) {
        p = p->next;
        length++;
    }
    return length;
}
// 按位查找:查找第i个结点
LNode *GetElem(LinkList &L, int i) {
    if (i < 0) {
        return NULL; // i值不合法
    }
    LNode *p = L;
    int j = 0;
    while (p != NULL && j < i) {
        p = p->next;
        j++;
    }
    return p;
}
// 按值查找:查找数据域为e的结点
LNode *GetLNode(LinkList &L, int e) {
    LNode *p = L->next;
    while (p != NULL && p->data != e) {
        p = p->next;
    }
    return p;
}
// 头插法建立单链表
LinkList List_HeadInsert(LinkList &L) {
    int e;
    cin >> e;
    while (e != 9999) {
        LNode *s = new LNode;
        s->data = e;
        s->next = L->next;
        L->next = s;
        cin >> e;
    }
    return L;
}
// 尾插法建立单链表
LinkList List_TailInsert(LinkList &L) {
    LNode *r = L; // r为尾指针
    int e;
    cin >> e;
    while (e != 9999) {
        LNode *s = new LNode;
        s->next = r->next;
        s->data = e;
        r->next = s;
        r = s; // 将r置为新的尾指针
        cin >> e;
    }
    r->next = NULL; // 尾指针的next置为NULL
    return L;
}
// 前插操作:在p结点之前插入数据e
bool InsertPriorNode(LNode *p, int e) {
    if (p == NULL) {
        return false;
    }
    LNode *s = new LNode;
    s->next = p->next;
    s->data = p->data; // 数据后移,模拟结点后移
    p->next = s;
    p->data = e; // 将前结点置为新插入的结点
    return true;
}
// 后插操作:在p结点之后插入数据e
bool InsertNextNode(LNode *p, int e) {
    if (p == NULL) {
        return false;
    }
    LNode *q = new LNode;
    q->data = e;
    q->next = p->next;
    p->next = q;
    return true;
}
// 按位序插入
bool InserstList(LinkList &L, int i, int e) {
    if (i < 1) { // i值不合法
        return false;
    }
    LNode *p = GetElem(L, i - 1); // 遍历查找i-1个结点
    InsertNextNode(p, 5244);      // 使用后插法
    
    return true;
}
// 删除p结点的后继结点
bool DeleteNextDNode(LNode *p) {
    if (p == NULL || p->next == NULL) {
        return false;
    }
    LNode *s = new LNode;
    s = p->next;
    p->next = s->next;
    delete s;
    return true;
}
// 删除指定结点
bool DeleteNode(LNode *p) {
    if (p == NULL) {
        return false;
    }
    LNode *s = new LNode;
    s = p->next;       // q指向被删除结点
    p->data = s->data; // 数据前移,模拟结点前移
    p->next = s->next; // 断开与被删除结点的联系
    delete s;
    return true;
}
// 按位序删除
bool ListDelte(LinkList &L, int i, int &e) {
    if (i < 1) {
        return false;
    }
    
    LNode *p = GetElem(L, i - 1);
    e = p->next->data;
    DeleteNextDNode(p);  // 删除前一结点的后继结点
    return true;
}
// 遍历单链表
void TraverseList(LinkList &L) {
    if (L->next == NULL) {
        return;
    }
    LNode *p = L->next; // 指向头指针
    while (p != NULL) {
        cout << p->data << " ";
        p = p->next;
    }
    cout << endl;
}
int main() {
    LinkList L;
    InitList(L);
    L = List_TailInsert(L); // 尾插法
    // L = List_HeadInsert(L);  // 头插法
    TraverseList(L);
    InserstList(L, 1, 5244);
    TraverseList(L);
    int e = -1;
    ListDelte(L, 3, e);
    cout << "被删除的值:" << e << endl;
    TraverseList(L);
    cout << "长度:" << GetLength(L) << endl;
    return 0;
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

--结束END--

本文标题: C++ 实现单链表创建、插入和删除

本文链接: https://www.lsjlt.com/news/154256.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++ 实现单链表创建、插入和删除
    目录C++单链表创建、插入和删除1.头节点插入和删除结果2.中间节点插入和删除结果3.尾结点插入和删除结果C++单链表(带头结点)总结归纳代码实现C++单链表创建、插入和删除 这里仅...
    99+
    2022-11-13
  • C语言实现顺序表的插入删除
    目录一、初始化顺序表属性二、顺序表的插入三、删除 首先声明一个顺序表的结构 (数组的第一个元素是0,但是顺序表的第一个一般 从1(人为设定)开始) #include <...
    99+
    2022-11-13
  • C语言二叉排序树的创建,插入和删除
    目录一、二叉排序树(二叉查找树)的概念二、二叉排序树的判别三、二叉排序树的创建(creat、insert)四、二叉排序树的插入五、二插排序树的删除六、完整代码(可以运行)总结一、二叉...
    99+
    2022-11-12
  • C语言如何实现顺序表的插入删除
    本文小编为大家详细介绍“C语言如何实现顺序表的插入删除”,内容详细,步骤清晰,细节处理妥当,希望这篇“C语言如何实现顺序表的插入删除”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。首先声明一个顺序表的结构 (数组的...
    99+
    2023-06-30
  • C语言如何实现头插法建立单链表
    目录怎么将结点一个个插入在某个结点前面呢?然后再在头结点的后面插入新的结点首先要明确一点,利用头插法建立出来的单链表的输出都是逆序的(就是和你的输入顺序反着来的)然后就是要明确生成的...
    99+
    2022-11-13
  • C++怎么实现链表插入排序
    本篇内容主要讲解“C++怎么实现链表插入排序”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++怎么实现链表插入排序”吧!链表插入排序链表的插入排序实现原理很简单,就是一个元素一个元素的从原链表...
    99+
    2023-06-20
  • C++实现LeetCode(147.链表插入排序)
    [LeetCode] 147. Insertion Sort List 链表插入排序 Sort a linked list using insertion sort. A graph...
    99+
    2022-11-12
  • C++实现LeetCode(237.删除链表的节点)
    [LeetCode] 237.Delete Node in a Linked List 删除链表的节点 Write a function to delete a node (exce...
    99+
    2022-11-12
  • C语言中如何实现单链表删除指定结点
    目录单链表删除指定结点链表的删除结点(各种方法)链表中删除第i个结点删除与链表中与a相同的结点删除链表中重复元素单链表删除指定结点 在单链表中删除指定的结点。这里单链表是用尾插法建立...
    99+
    2022-11-13
  • MongoDB实现创建删除数据库、创建删除表(集合 )、数据增删改查
    一、 数据库使用 开启 mongodb 服务:要管理数据库,必须先开启服务,开启服务使用  mongod --dbpath c:\mongodb 管理 mongodb 数据库:(一定要在新的 cmd 中输入...
    99+
    2022-06-26
    MongoDB 创建删除数据库 创建删除表 创建删除对象 数据增删改查
  • MongoDB实现创建删除数据库、创建删除表(集合)、数据增删改查
    一、 数据库使用 开启 mongodb 服务:要管理数据库,必须先开启服务,开启服务使用  mongod --dbpath c:\mongodb 管理 mongodb ...
    99+
    2022-11-13
  • MongoDB怎么实现创建删除数据库、创建删除表、数据增删改查
    这篇文章主要介绍“MongoDB怎么实现创建删除数据库、创建删除表、数据增删改查”,在日常操作中,相信很多人在MongoDB怎么实现创建删除数据库、创建删除表、数据增删改查问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对...
    99+
    2023-07-02
  • C语言之实现单链表指定结点的插入方式
    目录单链表指定结点的插入链表之在指定结点前面或后面插入新的结点单链表指定结点的插入 #include <bits/stdc++.h> using namespace st...
    99+
    2022-11-13
  • C++实现LeetCode(21.混合插入有序链表)
    [LeetCode] 21. Merge Two Sorted Lists 混合插入有序链表 Merge two sorted linked lists and return it ...
    99+
    2022-11-12
  • C#/VB.NET实现在Word中插入或删除脚注
    目录程序环境在Word中的特定段落后插入脚注完整代码效果图在Word中的特定文本后插入脚注完整代码效果图脚注,是可以附在文章页面的最底端的,对某些东西加以说明,印在书页下端的注文。脚...
    99+
    2023-03-08
    C# Word插入 删除脚注 C# Word插入脚注 C# Word 删除脚注 C# Word 脚注 C# Word
  • C++和python如何实现单链表
    这篇文章给大家分享的是有关C++和python如何实现单链表的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、链表的基本概念链表是数据元素的线性集合(Linear Collection),物理存储不连续。那么,这...
    99+
    2023-06-29
  • Java创建二叉搜索树,实现搜索,插入,删除的操作实例
    Java实现的二叉搜索树,并实现对该树的搜索,插入,删除操作(合并删除,复制删除)首先我们要有一个编码的思路,大致如下: 1、查找:根据二叉搜索树的数据特点,我们可以根据节点的值得比较来实现查找,查找值大于当前节点时向右走,反之向左走!2、...
    99+
    2023-05-30
    java 二叉搜索树 搜索
  • C++使用cjson操作Json格式文件(创建、插入、解析、修改、删除)
    目录为什么要学习解析Json文件?一、准备cJSON开源库二、cJSON介绍三、封装Json四、解析Json五、修改Json六、删除Json七、全部代码八、总结为什么要学习解析Jso...
    99+
    2022-11-13
  • DIV CSS如何实现表单输入单元点击删除
    这篇文章主要介绍DIV CSS如何实现表单输入单元点击删除,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!DIV CSS表单输入单元点击删除:本列同上则作用类似,只是使用鼠标上略有变化...
    99+
    2022-10-19
  • C#/VB.NET怎么实现在Word中插入或删除脚注
    本篇内容介绍了“C#/VB.NET怎么实现在Word中插入或删除脚注”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!程序环境本次测试时,在程序...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作