数据结构之单链表

1. 链表的特点

  • 链表是一种非线性、非顺序的物理结构,是由若干个节点组成。
  • 链表采用的是“见缝插针”的存储方法,不要求内存连续,靠next指针关联起来。
  • 链表的物理存储方式为随机存储,访问方式为顺序访问。
  • 查找节点的时间复杂度为O(n),插入、删除节点的时间复杂度为O(1)。
  • 链表适用于写操作多,读操作少的场景。
 1 //单向链表节点的数据结构
 2 struct SingleListNode
 3 {
 4     int   nData;//当前节点的数据
 5     Node* pNext;//指向下一个节点的指针
 6 };
 7
 8 //双向链表节点的数据结构
 9 struct DobuleListNode
10 {
11   int nData;//当前节点的数据
12   Node* pPre;//指向上一个节点的指针
13   Node* pNext;//指向下一个节点的指针
14 };

2. 链表的基本操作

链表的操作方式主要分为增、删、改、查,下面以单链表为例,分别以最简单的方式介绍基本用法。

首先定义一个单链表数据结构:

 1 struct SingleListNode
 2 {
 3     int             nVal;
 4     SingleListNode* pNext;
 5     SingleListNode():pNext(NULL){}
 6     SingleListNode(int nTempValue):nVal(nTempValue),pNext(NULL){}
 7 };
 8
 9 class SingleList
10 {
11 public:
12     SingleList():m_pHead(NULL),m_nSize(0){}
13     ~SingleList(){}
14 public:
15     SingleListNode* Find(int nIndex);
16     void            Insert(int nIndex,SingleListNode* pNode);
17     SingleListNode* Remove(int nIndex);
18     void            PrintList();
19 private:
20     SingleListNode* m_pHead;
21     int             m_nSize;
22 };

2.1 查找

链表节点的查找不能通过索引快速定位,只能从头节点开始查找。

 1 SingleListNode* SingleList::Find(int nIndex)
 2 {
 3     if(nIndex < 0 || nIndex >= m_nSize)
 4     {
 5         printf("SingleList::Find:failed! the index is out of range. index is %d \n",nIndex);
 6         return NULL;
 7     }
 8
 9     if(NULL == m_pHead)
10     {
11         printf("SingleList::Find:failed! the head node is null. \n");
12         return NULL;
13     }
14
15     SingleListNode* pRet = m_pHead;
16     for(int i = 0;i < nIndex;i++)
17     {
18         if(pRet)
19         {
20             pRet = pRet->pNext;
21         }
22     }
23     return pRet;
24 }

2.2 更新

首先从列表中查找待更新的节点,直接把旧数据替换为新值即可。

2.3 删除

删除分为三种情况:

  • 尾部删除:将倒数第二个节点的next指针只为空。
  • 头部删除:将链表头节点设为原头节点的next指针。
  • 中间删除:将前置节点的next指针指向待删除节点的next指针。中间删除和尾部删除可以采用同一段代码实现。
 1 SingleListNode* SingleList::Remove(int nIndex)
 2 {
 3     SingleListNode* pRet = NULL;
 4     if(nIndex < 0 || nIndex >= m_nSize)
 5     {
 6         printf("SingleList::Remove:failed! the index is out of range, size is %d .\n ",m_nSize);
 7         return pRet;
 8     }
 9
10     if(NULL == m_pHead)
11     {
12         printf("SingleList::Remove:failed! the head node is null. \n");
13         return NULL;
14     }
15
16     if(nIndex == 0)
17     {
18         pRet = m_pHead;
19         m_pHead = m_pHead->pNext;
20     }
21     else
22     {
23         SingleListNode* pPreNode = Find(nIndex - 1);
24         if(pPreNode == NULL)
25         {
26             printf("SingleList::Remove:failed! the pPre node is null.\n ");
27             return pRet;
28         }
29
30         pRet = pPreNode->pNext;
31         if(pRet)
32         {
33             pPreNode->pNext = pRet->pNext;
34             m_nSize--;
35         }
36     }
37
38     return pRet;
39 }

2.4 插入

  • 尾部插入:将尾节点的next指针指向新插入的节点。
  • 头部插入:首先将带插入的节点的next指针头节点,然后将新插入的节点设为链表头节点(注意顺序不能反)。
  • 中间插入:首先将新节点的next指针指向插入位置的节点,然后将原始插入位置节点的前置节点的next指针指向新节点(注意顺序不能反)。中间插入和尾部插入可以采用同一段代码实现。
 1 void SingleList::Insert(int nIndex,SingleListNode* pNode)
 2 {
 3     if(NULL == pNode)
 4     {
 5         printf("SingleList::Insert:failed! the pNode is null.\n ");
 6         return;
 7     }
 8
 9     if(nIndex < 0 || nIndex > m_nSize)
10     {
11         printf("SingleList::Insert:failed! the index is out of range, size is %d .\n ",m_nSize);
12         return;
13     }
14
15     if(nIndex == 0)
16     {
17         //first
18         pNode->pNext = m_pHead;
19         m_pHead = pNode;
20     }
21     else
22     {
23         SingleListNode* pPre = Find(nIndex - 1);
24         if(pPre == NULL)
25         {
26             printf("SingleList::Insert:failed! the pPre node is null.\n ");
27             return;
28         }
29
30         pNode->pNext = pPre->pNext;
31         pPre->pNext = pNode;
32     }
33     m_nSize++;
34 }

3. 链表的应用

常见的面试题中考察链表应用的场景有:

  • 两数相加
  • 判断链表中是否有环
  • 删除链表的倒数第N个节点
  • 反转链表(单链表)
  • 回文链表
  • 合并两个有序链表
    等等,后边会单独出一篇文章介绍面试中常见的链表算法题。

原文地址:https://www.cnblogs.com/calence/p/11409837.html

时间: 2024-10-11 14:37:23

数据结构之单链表的相关文章

C#数据结构-单链表

理论基础: 链表是用一组任意的存储单元来存储线性表中的数据元素. 如果结点的引用域只存储该结点直接后继结点的存储地址,则该链表叫单链表(Singly Linked List). 单链表由头引用H唯一确定.头引用指向单链表的第一个结点,也就是把单链表第一个结点的地址放在H中. C#实现: 1接口 引用线性表的接口IListDS<T> 2实现 首先,必须定义一个单链表的节点类.  1 public class Node<T> 2    { 3        private T data

数据结构之单链表(C++实现)

有一段时间没有写一些关于数据结构的程序了,正好算法导论这门课学到红黑树,感觉数据结构都忘得差不多了,而且考研还要考,故再拿来复习一下. 一.C++实现单链表 #include<iostream> using namespace std; typedef struct LNode { int data; struct LNode *next; }LNode,*LinkList; void CreateList_L(LinkList &L, int n) { L = new LNode()

数据结构之——单链表

今天闲来无事,就打算把大一的时候写过的数据结构重温一遍,基本上我在大一之后只在单片机上用过几次顺序表和循环队列之外再就很少使用过数据结构了. 并且乘着写一下数据结构也可以熟悉熟悉vim. 首先定义单链表节点: 1 #define DataType int 2 3 struct node{ 4 DataType data; 5 struct node *next; 6 }; 7 struct node list,*p_list; 单链表这个数据结构需要一些函数来对她操作,一般需要有这些: 1.初始

数据结构(一) 单链表的实现-JAVA

数据结构还是很重要的,就算不是那种很牛逼的,但起码得知道基础的东西,这一系列就算是复习一下以前学过的数据结构和填补自己在这一块的知识的空缺.加油.珍惜校园中自由学习的时光.按照链表.栈.队列.排序.数组.树这种顺序来学习数据结构这门课程把. -WH 一.单链表的概念 链表是最基本的数据结构,其存储的你原理图如下图所示 上面展示的是一个单链表的存储原理图,简单易懂,head为头节点,他不存放任何的数据,只是充当一个指向链表中真正存放数据的第一个节点的作用,而每个节点中都有一个next引用,指向下一

Java数据结构之单链表

链表的组成:链表头+结点 ? ?链表头一般只存储下一个节点的引用 ? ?节点:存数据+下一个节点的引用 链表头代码: package?com.xingej.algorithm.datastructure.linkedList.singleLinkedList; /** ?*?声明一个链表的头部 ?*? ?*?从链表头的使用,联想到hadoop,spark,netty中都有上下文context ?*? ?*[email protected]?erjun?2017年12月8日?上午8:45:08 ?

java数据结构:单链表常见操作代码实现

一.概述: 本文主要总结单链表常见操作的实现,包括链表结点添加.删除:链表正向遍历和反向遍历.链表排序.判断链表是否有环.是否相交.获取某一结点等. 二.概念: 链表: 一种重要的数据结构,HashMap等集合的底层结构都是链表结构.链表以结点作为存储单元,这些存储单元可以是不连续的.每个结点由两部分组成:存储的数值+前序结点和后序结点的指针.即有前序结点的指针又有后序结点的指针的链表称为双向链表,只包含后续指针的链表为单链表,本文总结的均为单链表的操作. 单链表结构: Java中单链表采用No

数据结构关于单链表的一些操作的源代码

单链表的可以有许多问题,这是我特意整理一下的有关他的相关操作,给出代码,有需要的可以自己调试,重要的就是关于环的一些操作: #include <iostream>#include <cstdio>#include <cstdlib>#include <ctime>using namespace std;typedef int Elemtype;typedef struct Node{ Elemtype data; struct Node *next;}Nod

数据结构:单链表结构字符串(python版)

1 #!/urs/bin/env python 2 # -*- coding:utf-8 -*- 3 4 #异常类 5 class stringTypeError(TypeError): 6 pass 7 8 #节点类 9 class Node(object): 10 def __init__(self, elem, next_ = None): 11 self.elem = elem 12 self.next = next_ 13 #单链表类 14 class single_list(obje

数据结构 C++ 单链表 一元多项式的相加

#include <iostream> using namespace std; struct Node { double coe; //系数 int exp; //指数 Node *next; }; void CreatPoly(Node *&head, int n) // 生成带表头结点的单链表,除头结点外另生成n个结点 { head = (Node *)new Node; head->coe = 0; head->exp = 0; head->next = NU