链表:也是线性表的一种。形象的来说:
就像火车的一个个车厢一样,一个个的链起来的。它有一个特点:它的头没有前驱,尾没有后继。
为什么会引入链表这个概念呢?之前我们知道的顺序表,是用数组的形式保存数据的。它使用起来也非常方便,优点在于它的尾删尾插非常方便,直接将数组空间大小加1,给最后一个数组赋值就ok了。但是对于数组来说,也有一定的缺点。比如:如果在中间插入或删除的话,就得移动一定得位数才可进行相关操作。最坏得情况是你在头插头删的时候,时间的消耗更巨大。为了避免这种重复的移位操作,我们引入了链表这个概念。链表的头插头删就容易多了,只需修改头节点的位置就好啦。
链表的种类很多,有单链表、双向链表、循环链表等。今天我们主要讲单链表。
那么链表的结构是怎么样的呢?
typedef int DataType;
struct Node
{
DataType data; //节点里存放的数据
struct Node* next; //指向下一个节点的指针
};
下面我们来一一实现它们吧~
//SList.h
#pragma once
#include<iostream>
using namespace std;
typedef int DataType;
typedef struct Node
{int data;struct Node* next;
}Node,*pNode;void InitSlist(pNode *pHead);void PushBack(pNode *pHead,DataType data);
void PopBack(pNode *pHead);void PushFront(pNode *pHead,DataType data);
void PopFront(pNode *pHead);
pNode BuyNode(DataType data);
pNode Find(pNode pHead, DataType data);
void Insert(pNode pos, DataType data); //某个位置插入datavoid Erase(pNode* pHead, pNode pos); //删除位置节点
void Remove(pNode* pHead, DataType data); //删除某个数据的节点
void RemoveAll(pNode* pHead, DataType data); //删除所有数据为data的节点
void Destroy(pNode* pHead); //销毁
int Empty(pNode pHead); //判空
int Size(pNode pHead); //节点数目
//SList.cpp
#include"SList.h"
#include<assert.h>void InitSlist(pNode *pHead)
{*pHead = NULL;
}pNode BuyNode(DataType data) //创建一个新节点
{pNode newNode = (pNode)malloc(sizeof(Node));assert(newNode);newNode->data = data;newNode->next = NULL;return newNode;
}void PushBack(pNode *pHead,DataType data)
{if(*pHead == NULL){*pHead = BuyNode(data);(*pHead)->next = NULL;}else{pNode pCur = *pHead;while(pCur->next){pCur = pCur->next;}pCur->next = BuyNode(data);}
}void PopBack(pNode *pHead)
{if(*pHead == NULL)return;if((*pHead)->next == NULL){free(*pHead);*pHead = NULL;}else{pNode pCur = *pHead;pNode pPrev = NULL;while(pCur->next){pPrev = pCur;pCur = pCur->next;}free(pCur);pPrev->next = NULL;}
}void PushFront(pNode *pHead,DataType data)
{if(*pHead == NULL)*pHead = BuyNode(data);else{pNode cur = BuyNode(data);cur->next = *pHead;*pHead = cur;}
}void PopFront(pNode *pHead)
{if(*pHead == NULL)return;else{pNode pDel = *pHead;*pHead = (*pHead)->next;free(pDel);}
}pNode Find(pNode pHead, DataType data)
{pNode pCur = pHead;while(pCur){if(pCur->data == data){return pCur;}pCur = pCur->next;}return NULL;
}void Insert(pNode pos, DataType data)
{pNode newNode = BuyNode(data);if(pos == NULL)return;newNode->next = pos->next;pos->next = newNode;
}void Erase(pNode* pHead, pNode pos)
{pNode pCur = *pHead;if(*pHead == pos && (*pHead)->next == NULL){free(pos);*pHead = NULL;return;}while(pCur){pNode pPrev = pCur;while(pPrev->next == pos){pNode pDel = pos;pPrev->next = pos->next;free(pDel);return;}pCur = pCur->next;}return;
}void Remove(pNode* pHead, DataType data)
{pNode pos = Find(*pHead,data);Erase(pHead,pos);
}void Destroy(pNode* pHead)
{while(*pHead){pNode pDel = *pHead;*pHead = (*pHead)->next;free(pDel);}return;
}int Empty(pNode pHead)
{return pHead == NULL;
}int Size(pNode pHead)
{pNode pCur = pHead;int count = 0;if(pHead == NULL)return 0;while(pCur){count++;pCur = pCur->next;}return count;
}void Print(pNode pHead)
{pNode pCur = pHead;while(pCur){cout<<pCur->data<<"->";pCur = pCur->next;}cout<<"NULL"<<endl;
}
对于单链表,我们还有一些有趣的题来和大家分享哦。
有趣的链表问题>>点击进入喽