C++编程语言实现单链表详情

目录
  • 一、单链表简单介绍
  • 二、下面我们先实现单链表的初始化。
  • 三、实现单链表的插入与删除数据

一、单链表简单介绍

首先,我们再回顾一下线性表的两种存储方式——顺序存储与链式存储

上图左边为顺序存储,右边为链式存储

之前我们利用数组来实现顺序表,对于顺序表的优点缺点,总结来说就是,查找方便,增删复杂。

线性表之顺序存储的优缺点

而链表特点可以说恰恰相反,增删方便,查找复杂。

今天实现的是链表中最简单的一种——单链表(每个结点中只含有一个指针域)

对于链表我们只知道它每个结点的存储的物理地址是不连续的,但逻辑上还是符合线性表“一对一”的特点。因此,我们就需要用“线”(指针)把这些不连续的结点按顺序连接起来。

链表的结点在内存中存储不连续

通过指针把每个结点按顺序连起来

到这里我们可以发现,要想表示链表中的结点,光存储结点的数据是不够的,还得有指针。因此,单链表的结点结构如下:

数据域存储数据,指针域存储指针

//================线性表的单链表存储结构=================
typedef struct LNode {
ElemType data;//数据域
struct LNode *next;//指针域
}LNode;

注意:因为指针是指向每个结点的,也就是指向struct LNode这个自定义的结构体类型,所以指针的类型就是struct LNode*。

二、下面我们先实现单链表的初始化。

单链表的初始化其实就是创建几个结点,然后用指针把他们连接起来。

先创建一个头指针,实际上就是创建一个头结点,然后头指针指向头结点就OK

LNode* CreateList_L(int n) {//顺位序输入n个元素的值,建立带表头结点的单链线性表L
 LNode *p = (LNode*)malloc(sizeof(LNode));//创建头结点(p也就是头指针)
 LNode *temp = p;//声明一个指针指向头结点,用于遍历链表(不是头指针,因为它只是暂时指向头结点)
 //生成链表
 for (int i = n; i > 0; --i)
 {
  LNode *node = (LNode *)malloc(sizeof(LNode));//创建结点
  if (node){//分配地址成功
   scanf_s("%c", &(node->data));
   node->next = NULL;
   //建立新结点与直接前驱结点的逻辑关系
   temp->next = node;
   temp = temp->next;
  }
  else {//如果分配地址失败,则返回错误信息
    printf("结点创建失败!\n");
  }
 }
 return p;
}

三、实现单链表的插入与删除数据

单链表插数据情况

观察可知,我们要实现插入操作,需要的操作是一样的。

S1:将后继结点的指针赋给新结点的指针域;

S2:将前驱节点的指针域改为指向新结点的指针。

注意:S1和S2不能换顺序。

//===============================算法2.9==========================
Status ListInsert_L(LNode *L, int i, ElemType e) {
 //在带头结点的单链表L中第i个位置之前插入元素e
 int j = 0;
 LNode *p = L;
 while (p&&j < i - 1) {
  p = p->next;
  ++j;
 }//寻找第i-1个结点
 if (!p || j > i - 1)return ERROR;//i小于1或者大于表长时
 LNode* s = (LNode*)malloc(sizeof(LNode));//生成新的结点
 s->data = e; s->next = p->next;//S1
 p->next = s;//S2
 return OK;
}

单链表删除数据示意图

观察可知,只需要将待删结点的前驱结点的指针域的值换成待删结点的后继结点的指针即可。

//=====================算法2.10=================================
Status ListDelete_L(LNode *L, int i, ElemType *e) {
 //在带头结点的单链表L中,删除第i个元素,并由e返回其值
 LNode *p = L;
 int j = 0;
 while (p->next&&j < i - 1) {//寻找第i个结点,并令p指向其前驱
  p = p->next; ++j;
 }
 if (!(p->next) || j > i - 1)return ERROR;//删除位置不合理
 LNode *q = p->next; p->next = q->next;//删除并释放结点
 *e = q->data; free(q);
 return OK;
}
三、参考代码实现与截图
#include<stdio.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define ElemType char
typedef int Status;
//================线性表的单链表存储结构==================
typedef  struct LNode {
 ElemType data;//数据域
 struct LNode *next;//指针域
}LNode;
LNode* CreateList_L(int n) {//顺位序输入n个元素的值,建立带表头结点的单链线性表L
 LNode *p = (LNode*)malloc(sizeof(LNode));//创建头结点
 LNode *temp = p;//声明一个指针指向头结点,用于遍历链表(不是头指针)
 //生成链表
 for (int i = n; i > 0; --i)
 {
  LNode *node = (LNode *)malloc(sizeof(LNode));//创建结点
  if (node){//分配地址成功
   scanf_s("%c", &(node->data));
   node->next = NULL;
   //建立新结点与直接前驱结点的逻辑关系
   temp->next = node;
   temp = temp->next;
  }
  else {//如果分配地址失败,则返回错误信息
    printf("结点创建失败!\n");
  }
 }
 return p;
}
//===============================算法2.9==========================
Status ListInsert_L(LNode *L, int i, ElemType e) {
 //在带头结点的单链表L中第i个位置之前插入元素e
 int j = 0;
 LNode *p = L;
 while (p&&j < i - 1) {
  p = p->next;
  ++j;
 }//寻找第i-1个结点
 if (!p || j > i - 1)return ERROR;//i小于1或者大于表长时
 LNode* s = (LNode*)malloc(sizeof(LNode));//生成新的结点
 s->data = e; s->next = p->next;
 p->next = s;
 return OK;
}
//=====================算法2.10=================================
Status ListDelete_L(LNode *L, int i, ElemType *e) {
 //在带头结点的单链表L中,删除第i个元素,并由e返回其值
 LNode *p = L;
 int j = 0;
 while (p->next&&j < i - 1) {//寻找第i个结点,并令p指向其前驱
  p = p->next; ++j;
 }
 if (!(p->next) || j > i - 1)return ERROR;//删除位置不合理
 LNode *q = p->next; p->next = q->next;//删除并释放结点
 *e = q->data; free(q);
 return OK;
}
void display(LNode *L) {
 LNode *temp =L;//将temp指针重新指向头结点
 //只要temp指针指向的结点的next不是Null,就执行输出语句。
 while (temp->next) {
  temp = temp->next;
  printf("%c", temp->data);
 }
 printf("\n");
}
int   main() {
 LNode *L = NULL;
 L=CreateList_L(5);
 display(L);
 ListInsert_L(L, 2, 'Y');
 display(L);
 ElemType e;
 ListDelete_L(L, 2, &e);
 display(L);
 printf("返回值为:%c", e);
 system("pause");
 return 0;
}

初始化链表为abcdef,在第2个位置插入Y,然后删除Y

到此这篇关于C++编程语言实现单链表详情的文章就介绍到这了,更多相关C++编程语言实现单链表内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++实现LeetCode(142.单链表中的环之二)

    [LeetCode] 142. Linked List Cycle II 单链表中的环之二 Given a linked list, return the node where the cycle begins. If there is no cycle, return null. To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexe

  • C++ 实现静态单链表的实例

    C++ 实现静态单链表的实例 利用数组实现的静态单链表,与严蔚敏书实现略有不同,不另设回收空间.有任何BUG或错误,希望各位朋友多多反馈~~感激不尽 /* Author : Moyiii * Mail: lc09@vip.qq.com * 静态链表实现,仅作学习之用,当然如果 * 你想拿去用,随你好啦. */ #include <iostream> using namespace std; #define MAX_LIST_SIZE 100 class Node { public: int d

  • 利用C++简单实现顺序表和单链表的示例代码

    本文主要给大家介绍了关于C++实现顺序表和单链表的相关内容,分享出来供大家参考学习,话不多说,来一起看看详细的介绍: 一.顺序表示例代码: #include <assert.h> #include <iostream> using namespace std; typedef int Datatype; class SeqList { public: SeqList() :_array(NULL) ,_size(0) ,_capacity(0) { } SeqList(const

  • C++实现LeetCode(141.单链表中的环)

    [LeetCode] 141. Linked List Cycle 单链表中的环 Given a linked list, determine if it has a cycle in it. To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to.

  • C++使用模板实现单链表(类外实现)

    本文实例为大家分享了C++使用模板实现单链表的具体代码,供大家参考,具体内容如下 这一篇可以和上一篇点击打开链接 模板实现单链表进行对比 看类外实现和类内实现的区别 代码: #include <iostream> using namespace std; template<typename T> class CLink { public: class Node; CLink();//无参的构造函数 void InsertHead(T data);//头插 void InsertTa

  • C++中单链表的建立与基本操作

    准备数据 准备在链表操作中需要用到的变量及数据结构 示例代码如下: 复制代码 代码如下: struct Data   //数据结点类型 { string key;  //关键字  string name; int age;};struct CLType  //定义链表结构 { Data nodeData; Data *nextNode;}; 定义了链表数据元素的类型Data以及链表的数据结构CLType.结点的具体数据保存在一个结构Data中,而指针nextNode用来指向下一个结点. 我们可以

  • C++单链表实现大数加法

    本文实例为大家分享了C++单链表实现大数加法,供大家参考,具体内容如下 Input Format 输入文件包括两行. 第一行包括一个正整数,保证位数不超过1000000. 第二行包括一个正整数,保证位数不超过1000000. Output Format 输出文件包括一行. 第一行包括一个正整数. Sample Input 10558 22 Sample Output 10580 #include <iostream> using namespace std; class BigData { f

  • C++实现单链表的构造

    单链表的构造,包括最常用函数,setData(),Insert(),Remove(),getData(),Search(). 代码如下: #include <iostream> #include <stdlib.h> using namespace std; template<class T> struct LinkNode{ T data; LinkNode<T> *link; LinkNode(LinkNode<T> *ptr=NULL){l

  • C++使用模板实现单链表

    本文实例为大家分享了用模板实现单链表,供大家参考,具体内容如下 话不多说 直接上代码 #include <iostream> using namespace std; template<typename E> class CLink; template<typename T> class Node { friend class CLink<T>; public: /* 构造函数和析构函数一般不加类型参数 本类类中除了构造函数和析构函数以外 其它的地方都要加上

  • C++编程语言实现单链表详情

    目录 一.单链表简单介绍 二.下面我们先实现单链表的初始化. 三.实现单链表的插入与删除数据 一.单链表简单介绍 首先,我们再回顾一下线性表的两种存储方式--顺序存储与链式存储 上图左边为顺序存储,右边为链式存储 之前我们利用数组来实现顺序表,对于顺序表的优点缺点,总结来说就是,查找方便,增删复杂. 线性表之顺序存储的优缺点 而链表特点可以说恰恰相反,增删方便,查找复杂. 今天实现的是链表中最简单的一种--单链表(每个结点中只含有一个指针域) 对于链表我们只知道它每个结点的存储的物理地址是不连续

  • C语言实现单链表反转

    一.理解指针 看懂链表的结构并不是很难,但是一旦把它和指针混在一起,就很容易让人摸不着头脑.所以,要想写对链表代码,首先就要理解好指针. 有些语言有"指针"的概念,比如 C 语言:有些语言没有指针,取而代之的是"引用",比如 Java.Python.不管是"指针"还是"引用",实际上,它们的意思都是一样的,都是存储所指对象的内存地址. 将某个变量赋值给指针,实际上就是将这个变量的地址赋值给指针,或者反过来说,指针中存储了这个变

  • 如何使用rust实现简单的单链表

    目录 前言 1.链表节点的定义 2.链表的定义 3.实现从链表头部插入节点的prepend方法 4.为链表实现Display trait定制链表的打印显示 5.为链表实现翻转链表功能的reverse方法 注意事项 总结 前言 作为初学者,在掌握了rust的基本语法和所有权机制,尝试写一下常见数据结构和算法,目标是为了更好的理解rust的所有权机制. 受限于个人目前对rust仍处于入门阶段,因此本文代码实现不一定是最合适的,甚至可能存在问题. 今天的目标是用rust实现一个简单的单链表Linked

  • C语言单链表实现多项式相加

    本文实例为大家分享了C语言单链表实现多项式相加的具体代码,供大家参考,具体内容如下 //多项式的相加和相乘 #include<stdio.h> #include<stdlib.h> #pragma warning(disable:4996)//兼容scanf typedef struct node { int coef; int expon; struct node* link; }Polynode,*Polynomial; Polynomial InsertPolyLinklis

  • Python单链表简单实现代码

    本文实例讲述了Python单链表简单实现代码.分享给大家供大家参考,具体如下: 用Python模拟一下单链表,比较简单,初学者可以参考参考 #coding:utf-8 class Node(object): def __init__(self, data): self.data = data self.next = None class NodeList(object): def __init__(self, node): self.head = node self.head.next = No

  • Java实现单链表翻转实例代码

    Java实现单链表反转,递归和非递归两种形式 /** * 反转单链表 */ /** * 定义链表 * * @author 16026 * */ class Node { int val; Node next; public Node(int val) { this.val = val; } } public class ReverseList { /** * 反转链表 * * @param head * @return */ public static Node reverseList(Node

  • java 实现单链表逆转详解及实例代码

    java 实现单链表逆转详解 实例代码: class Node { Node next; String name; public Node(String name) { this.name = name; } /** * 打印结点 */ public void show() { Node temp = this; do { System.out.print(temp + "->"); temp = temp.next; }while(temp != null); System.o

  • Java单链表的实现代码

    下面是小编给大家分享的一个使用java写单链表,有问题欢迎给我留言哦. 首先定义一个Node类 public class Node { protected Node next; //指针域 public int data;//数据域 public Node( int data) { this. data = data; } //显示此节点 public void display() { System. out.print( data + " "); } } 接下来定义一个单链表,并实现

  • Java单链表基本操作的实现

    最近被问到链表,是一个朋友和我讨论Java的时候说的.说实话,我学习编程的近一年时间里,学到的东西还是挺少的.语言是学了Java和C#,关于Web的学了一点Html+css+javascript.因为比较偏好,学习WinForm时比较认真,数据库操作也自己有所研究.但链表这个东西我还真没有学习和研究过,加上最近自己在看WPF,而课程也到了JSP了,比较紧. 但是我还是抽了一个晚上加半天的时间看了一下单向链表.并且使用Java试着写了一个实例出来.没有接触过链表的朋友可以作为参考,希望大家多提宝贵

  • Java模拟单链表和双端链表数据结构的实例讲解

    模拟单链表 线性表: 线性表(亦作顺序表)是最基本.最简单.也是最常用的一种数据结构. 线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的. 线性表的逻辑结构简单,便于实现和操作. 在实际应用中,线性表都是以栈.队列.字符串等特殊线性表的形式来使用的. 线性结构的基本特征为: 1.集合中必存在唯一的一个"第一元素": 2.集合中必存在唯一的一个 "最后元素" : 3.除最后一个元素之外,均有 唯一的后继(后件):

随机推荐