網站首頁 編程語言 正文
單鏈表
鏈表內存空間不一定連續(xù),其擴展性較好。多余的不多說了。該文主要記錄單鏈表的實現(xiàn),該單鏈表含有一個非空的頭節(jié)點。鏈表的操作實際上是對其指針域與數(shù)據(jù)域的操作。
線性表的鏈式存儲又稱為單鏈表,它是指通過一組任意的存儲單元來存儲線性表中的數(shù)據(jù)元素。為了建立數(shù)據(jù)元素之間的線性關系,對每個鏈表結點,除存放元素自身的信息外,還需要存放一個指向其后繼的指針。
單鏈表中結點類型的描述如下:
typedef struct LNode{ // 定義單鏈表節(jié)點類型
ElemType data; // 數(shù)據(jù)域
struct LNode* next; // 指針域
};LNode, *LinkList;
單鏈表的基本操作
1.初始化
單鏈表的初始化操作就是構造一個空表。
具體代碼:
// 初始化單鏈表
void InitList(LinkList &L) // 構造一個空的單鏈表L
{
L=new LNode; // 生成新節(jié)點作為頭節(jié)點,用頭指針L指向頭節(jié)點
L->next=NULL; // 頭節(jié)點的指針域置空
}
2.取值
和順序表不同,在鏈表中并沒有存儲在物理相鄰的單元中。所以我們只能從鏈表的首節(jié)點出發(fā),順著鏈域next逐個節(jié)點向下訪問。
具體代碼:
// 單鏈表的取值
bool GetElem(LinkList L, int i, ElemType &e)
{
LinkList p=L->next;int j=1; // 初始化,p指向首元節(jié)點,計數(shù)器j初值為1
while(p&&j<i) // 順著鏈域向后查找,直到p為空或p指向第i個元素
{
p=p->next; // p指向下一個節(jié)點
++j; // 計數(shù)器j相應加1
}
if(!p||j>i)return false; // i值不合法
e=p->data; // 取第i個節(jié)點的數(shù)據(jù)域
return true;
}
3.查找
從鏈表的首元節(jié)點出發(fā),依次將節(jié)點值和給定值e進行比較,返回查找結果。
具體代碼:
//單鏈表的查找
bool LocateElem(LinkList L, LNode*& p, ElemType e)
{
//在單鏈表中查找第一個數(shù)據(jù)為e的結點
p = L->next;//p指向首元結點
while (p && p->data != e)
{
p = p->next;
}
if (p)
{
return true;
}
return false;
}
4.插入
// 單鏈表的插入
bool ListInsert(LinkList &L, int i, ElemType e)
{
LinkList p = L;
LNode* s;
int j = 0;
while (p && j < i - 1)//p指向第i-1個結點
{
p = p->next;
j++;
}
if (!p || i < 1)//i大于表長+1或小于1,插入位置不合法
{
return false;
}
s = new LNode;
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
5.刪除
//單鏈表的刪除
bool ListDelete(LinkList& L, int i, ElemType& e)
{
//將單鏈表的第i個結點刪除
LinkList p = L;
LNode* q;
int j = 0;
while (p->next && j < i - 1)//p指向第i-1個結點
{
p = p->next;
j++;
}
if (!(p->next) || i < 1)//i大于表長或小于1,刪除位置不合法
{
return false;
}
q = p->next;//臨時保存被刪結點的地址以備釋放
p->next = q->next;
e = q->data;//保存被刪結點的數(shù)據(jù)
delete q;//釋放被刪結點的空間
return true;
}
示例代碼
直接上代碼:
LinkList.h
#pragma once
typedef struct LINKLIST {
void * data;
struct LINKLIST *pNext;
}LinkList;
typedef void(*PrintLinkList)(void *);
//無頭的鏈表
class LinkNode
{
public:
LinkNode();
~LinkNode();
void insertLinkList(int pos,void * data);
void removeByPosInLinkList(int pos);
int getSizeLinkList();
int findValueInLinkList(void* value);
LinkList* getFirstNodeLinkList();
void printLinkList(PrintLinkList print);
private:
LinkList *m_pHead;
int m_size;
};
LinkList.cpp
// LinkList.cpp
//
#include "LinkList.h"
#include <iostream>
using namespace std;
LinkNode::LinkNode()
{
m_pHead = new LinkList;
m_pHead->data = nullptr;
m_pHead->pNext = nullptr;
m_size = 0;
}
LinkNode::~LinkNode()
{
if (m_pHead != nullptr)
{
while (m_pHead != nullptr)
{
LinkList *pNext = m_pHead->pNext;
delete m_pHead;
m_pHead = nullptr;
m_pHead = pNext;
}
}
}
void LinkNode::insertLinkList(int pos, void * data)
{
if (m_pHead == nullptr)
{
return;
}
if (data == nullptr)
{
return;
}
//插入位置矯正
if (pos < 0 || pos > m_size )
{
pos = m_size;
}
LinkList * insertNode = new LinkList;
insertNode->data = data;
insertNode->pNext = nullptr;
//找到前一個位置(pos從0開始)
LinkList *pPre = m_pHead;
for (int i = 0; i < pos; ++i)
{
pPre = pPre->pNext;
}
//有頭節(jié)點的鏈表
insertNode->pNext = pPre->pNext;
pPre->pNext = insertNode;
m_size++;
}
void LinkNode::removeByPosInLinkList(int pos)
{
if (m_pHead == nullptr)
{
return;
}
if (pos < 0 || pos >= m_size)
{
return ;
}
//找到前一個位置(pos從0開始)
LinkList *pPre = m_pHead;
for (int i = 0; i < pos; ++i)
{
pPre = pPre->pNext;
}
LinkList *delNode = pPre->pNext;
pPre->pNext = delNode->pNext;
delete delNode;
delNode = nullptr;
m_size--;
}
int LinkNode::getSizeLinkList()
{
return m_size;
}
int LinkNode::findValueInLinkList(void* value)
{
int nPos = -1;
if (m_pHead == nullptr)
{
return nPos;
}
if (value == nullptr)
{
return nPos;
}
LinkList *pHead = m_pHead;
for (int i = 0; i < m_size; ++i)
{
//有空的頭節(jié)點
pHead = pHead->pNext;
if (pHead->data == value)
{
nPos = i;
break;
}
}
return nPos;
}
LinkList * LinkNode::getFirstNodeLinkList()
{
if (m_pHead == nullptr)
{
return nullptr;
}
return m_pHead->pNext;//有空的頭節(jié)點
}
void LinkNode::printLinkList(PrintLinkList print)
{
if (m_pHead == nullptr)
{
return ;
}
//不能直接移動頭節(jié)點,需要保留頭節(jié)點
LinkList *pTemp = m_pHead;
pTemp = pTemp->pNext;
while (pTemp != nullptr)
{
print(pTemp->data);
pTemp = pTemp->pNext;
}
cout << endl;
}
mian.cpp
#include <iostream>
#include "LinkList.h"
using namespace std;
typedef struct PERSON {
char name[64];
int age;
int score;
}Person;
void myPrint(void *data)
{
Person *p = (Person*)data;
cout << "name : " << p->name << " age: " << p->age << " score: " << p->score << endl;
}
void test()
{
LinkNode *plinkList = new LinkNode;
Person p1 = {"husdh",23,78};
Person p2 = { "hudfs",23,98 };
Person p3 = { "術后",23,78 };
Person p4 = { "喀什",23,67 };
plinkList->insertLinkList(0, &p1);
plinkList->insertLinkList(1, &p2);
plinkList->insertLinkList(2, &p3);
plinkList->insertLinkList(3, &p4);
plinkList->printLinkList(myPrint);
cout <<"鏈表的節(jié)點數(shù): "<< plinkList->getSizeLinkList() << endl;
plinkList->removeByPosInLinkList(1);
cout << "remove" << endl;
plinkList->printLinkList(myPrint);
cout << "刪除后鏈表的節(jié)點數(shù): " << plinkList->getSizeLinkList() << endl;
cout << "p3位置: " << plinkList->findValueInLinkList(&p3) << endl;
myPrint(plinkList->getFirstNodeLinkList()->data);
delete plinkList;
plinkList = nullptr;
}
int main()
{
test();
return 0;
}
以上是單鏈表實現(xiàn)及測試代碼。
開發(fā)環(huán)境
vs2017控制臺輸出程序。
運行結果
以上僅記錄,方便理解。
原文鏈接:https://blog.csdn.net/blqzj214817/article/details/125316408
相關推薦
- 2022-02-27 uniapp swiper內有點擊事件時會觸發(fā) swiper的animationfinish事件
- 2022-06-02 python套接字socket通信_python
- 2022-12-05 Windows的sc命令詳解(sc命令用法)_DOS/BAT
- 2022-12-06 React深入分析useEffect源碼_React
- 2022-07-18 spring boot 中解決 Invalid character found in the req
- 2022-11-18 Shell實現(xiàn)批量操作文件的方法詳解_linux shell
- 2022-10-27 在Rust?web服務中使用Redis的方法_Redis
- 2022-04-05 C語言用遞歸函數(shù)實現(xiàn)漢諾塔_C 語言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結構-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支