当前位置: 首页 > news >正文

广东省建设工程造价管理协会网站品牌传播推广方案

广东省建设工程造价管理协会网站,品牌传播推广方案,优化排名工具,怎么做网站推广临沂专栏:数据结构 个人主页:HaiFan. 专栏简介:从零开始,数据结构!! 单链表前言顺序表的缺陷链表的概念以及结构链表接口实现打印链表中的元素SLTPrintphead->next!NULL和phead!NULL的区别开辟空间SLTNewNod…

专栏:数据结构
个人主页:HaiFan.
专栏简介:从零开始,数据结构!!

单链表

  • 前言
  • 顺序表的缺陷
  • 链表的概念以及结构
  • 链表接口实现
  • 打印链表中的元素SLTPrint
    • phead->next!=NULL和phead!=NULL的区别
  • 开辟空间SLTNewNode
  • 尾插SLTPushBack和尾删SLTPopBack
  • 头插SLTPushFront和头删SLTPopFront
  • 查找SLTFind
  • 在查找元素的后面插入SLTInsertAfter
  • 在查找元素的后面删除SLTEraseAfter
  • 销毁开辟的空间SLTDestory
  • 各个接口测试
  • 源代码
  • 链表和顺序表的区别

前言

在这里插入图片描述

顺序表的缺陷

顺序表每一次扩容,都是连续的空间,支持通过下标去访问数据。

但是顺序表的头插,头删,中间删元素,需要把后面的数据覆盖前面的元素,也就是挪动元素,这就导致效率非常的低

并且,顺序表在扩容之后,可能会有一部分空间没有用,这就导致了空间浪费。

链表的概念以及结构

链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 。

链表的结点一般是在堆上申请出来的,从堆上申请的空间,是按照一定策略来分配的,两次申请的空间可能连续,也可能不连续。

链表是每用一块空间,便开辟一块空间,因此,不会造成空间浪费。

在这里插入图片描述

这个图什么意思呢?

把开辟的空间当作2个合在一起的小方块,一个小方块用来存元素的值,一个方块用来存放下一个空间的地址。

在这里插入图片描述

当这个1就是最后一个元素的时候,这个下一块空间的地址就是NULL,因为1后面没有元素了,不能让这个地址乱指向其他的空间。

链表接口实现

在这里插入图片描述

这里,在结构体中要用结构体指针,指针就是地址,这个地址就是用来存放下一个空间的地址的。

typedef int SLTDataType;typedef struct SLTNode
{SLTDataType val;struct SLTNode* next;
}SLT;void SLTPrint(SLT* phead);//打印单链表中的数据SLT* SLTNewNode(SLTDataType x);//每要插入数据,就需要开一一块空间void SLTPushBack(SLT** pphead, SLTDataType x);//尾插
void SLTPopBack(SLT** pphead);//尾删void SLTPushFront(SLT** pphead, SLTDataType x);//头插
void SLTPopFront(SLT** pphead);//头删SLT* SLTFind(SLT** pphead, SLTDataType x);//查找
//单链表在pos位置之后插入x
void SLTInsertAfter(SLT* pos, SLTDataType x);//插入
//单链表在pos位置之后删除元素
void SLTEraseAfter(SLT* pos);//删除void SLTDestory(SLT** pphead);//销毁空间

打印链表中的元素SLTPrint

打印链表中的元素是最容易实现的一个接口。

void SLTPrint(SLT* phead)
{while (phead != NULL){cout << phead->val << "->";phead = phead->next;}cout << "NULL" << endl;
}

这里用一级指针,因为打印链表不会更改链表中的一些东西。

每打印出一个元素,都让phead指向下一块空间,直到走到为NULL的时候为止

在这里插入图片描述

phead->next!=NULL和phead!=NULL的区别

在这里插入图片描述

假如现在phead是在3这块空间,那么phead->next就是指向下一块空间,因为下一块空间是NULL,所以,当你写出phead->next != NULL的时候,就会在3这里停止后面的打印。


phead !=NULL是当phead走到NULL的时候才会执行。

开辟空间SLTNewNode

链表是每用一块空间就开辟一块空间。这样不会造成空间浪费。

SLT* SLTNewNode(SLTDataType x)
{SLT* newnode = (SLT*)malloc(sizeof(SLT));newnode->next = NULL;newnode->val = x;return newnode;
}

开辟了空间之后,不要忘记把newnode->next置为NULL,不然就成为野指针了。最后把这块空间返回即可。

尾插SLTPushBack和尾删SLTPopBack

尾插的时候,先调用一下开辟空间的函数,再把开辟的空间返回,用一个结构体指针变量接收。

  1. 当链表为空的时候,newnode就可以当作链表中的第一块空间。
  2. 当链表不为空的时候,就需要先找到链表的尾部,然后把newnode链接在链表中即可
void SLTPushBack(SLT** pphead, SLTDataType x)
{SLT* newnode = SLTNewNode(x);if (*pphead == NULL){*pphead = newnode;}else{SLT* tail = *pphead;while (tail->next != NULL){tail = tail->next;}tail->next = newnode;}
}

在这里插入图片描述

要用一个临时变量走向链表最后一个元素的位置,如果不用临时变量,直接用头元素走到最后一个位置,那么,在打印元素的时候,也是从最后一个元素的位置开始打印的,前面的元素不会打印,因为我们是用指针接收的头元素的位置,通过指针直接去访问内容,指针走到最后就会导致,原本应该指向头元素的指针,就指向了最后的元素。

所以在这里用 tail->next != NULL


尾删分两种情况,当链表中只有一个元素的时候和链表中有n个元素的时候。

第一种情况好说,直接把第一个元素的空间给free掉,在置为空即可。

第二种情况就是先找到尾,但是,在找到尾部之后,不能直接把尾部free掉,而是要先知道倒数第二个元素的位置。

void SLTPopBack(SLT** pphead)
{assert(*pphead);if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SLT* tail = *pphead;while (tail->next->next != NULL){ tail = tail->next;}free(tail->next);tail->next = NULL;}
}/*SLTNode* prev = NULL;SLTNode* tail = phead;while (tail->next){prev = tail;tail = tail->next;}free(tail);prev->next = NULL;*/

这两种方法都可以。

头插SLTPushFront和头删SLTPopFront

头插特别容易,先开辟一块空间,然后把这块空间指向头元素空间。在把头元素空间指向新开辟的空间即可。

在这里插入图片描述

void SLTPushFront(SLT** pphead, SLTDataType x)
{SLT* newnode = SLTNewNode(x);newnode->next = *pphead;*pphead = newnode;
}

头删之前,要先判断链表中有没有元素,没有元素直接断言。

有一个元素,直接free。

多个元素,先用一个临时变量记录一下头元素指向的下一个元素的地址,然后把头元素给free掉,再让头元素=临时变量。

void SLTPopFront(SLT** pphead)
{assert(*pphead);if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SLT* head = (*pphead)->next;free(*pphead);*pphead = NULL;*pphead = head;}
}

查找SLTFind

查找元素的时候,把该空间的地址给返回即可,遍历一遍链表即可实现。

SLT* SLTFind(SLT** pphead, SLTDataType x)
{SLT* tail = *pphead;while (tail != NULL){if (tail->val == x){return tail;}tail = tail->next;}return NULL;//没有找到
}

在查找元素的后面插入SLTInsertAfter

先通过SLTFind,找到要插入的位置,然后通过断言来判断这个位置是否合法。

在这里插入图片描述

比如要把3插入到1和2之间,把3->next = 1->next,再把1->next = 3就能完成插入。

void SLTInsertAfter(SLT* pos, SLTDataType x)
{assert(pos);SLT* newnode = SLTNewNode(x);newnode->next = pos->next;pos->next = newnode;}

在查找元素的后面删除SLTEraseAfter

还是先断言,判断位置是否合法。

在这里插入图片描述
电脑上的画图实在是用不来,原谅我------。。。

void SLTEraseAfter(SLT* pos)
{assert(pos);if (pos->next == NULL){return;}SLT* newnode = pos->next;pos->next = newnode->next;free(newnode);newnode = NULL;
}

销毁开辟的空间SLTDestory

因为空间不一定是连续的,所以需要遍历链表,一个一个的释放

void SLTDestory(SLT** pphead)
{SLT* cur = *pphead;while (cur){SLT* hh = cur->next;free(cur);cur = hh;}
}

各个接口测试

void TestSLTNode()
{SLT* plist = NULL;cout << "尾插尾删" << endl;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPushBack(&plist, 4);SLTPopBack(&plist);SLTPopBack(&plist);SLTPopBack(&plist);SLTPopBack(&plist);SLTPrint(plist);
}void TestSLTNode1()
{SLT* plist = NULL;cout << "头插头删" << endl;SLTPushFront(&plist, 1);SLTPushFront(&plist, 2);SLTPushFront(&plist, 3);SLTPushFront(&plist, 4);SLTPopFront(&plist);SLTPopFront(&plist);SLTPopFront(&plist);SLTPrint(plist);
}void TestSLTNode2()
{SLT* plist = NULL;cout << "查找,删除,插入" << endl;SLTPushFront(&plist, -1);SLTPushBack(&plist, 1);SLTPushFront(&plist, -2);SLTPushBack(&plist, 2);SLTPushFront(&plist, -3);SLTPushBack(&plist, 3);SLTPushFront(&plist, -4);SLTPushBack(&plist, 4);SLT* ret = SLTFind(&plist, 3);if (ret){cout << ret << endl;}SLTPrint(plist);SLTInsertAfter(ret, 100);SLTInsertAfter(ret, 100);SLTInsertAfter(ret, 100);SLTPrint(plist);SLTEraseAfter(ret);SLTEraseAfter(ret);SLTPrint(plist);SLTDestory(&plist);
}int main()
{TestSLTNode();TestSLTNode1();TestSLTNode2();return 0;
}

在这里插入图片描述

源代码

.h文件

#pragma once#include <iostream>
#include <stdlib.h>
#include <assert.h>using namespace std;typedef int SLTDataType;typedef struct SLTNode
{SLTDataType val;struct SLTNode* next;
}SLT;void SLTPrint(SLT* phead);//打印单链表中的数据SLT* SLTNewNode(SLTDataType x);//每要插入数据,就需要开一一块空间void SLTPushBack(SLT** pphead, SLTDataType x);//尾插
void SLTPopBack(SLT** pphead);//尾删void SLTPushFront(SLT** pphead, SLTDataType x);//头插
void SLTPopFront(SLT** pphead);//头删SLT* SLTFind(SLT** pphead, SLTDataType x);//查找
//单链表在pos位置之后插入x
void SLTInsertAfter(SLT* pos, SLTDataType x);//插入
//单链表在pos位置之后删除元素
void SLTEraseAfter(SLT* pos);//删除void SLTDestory(SLT** pphead);//销毁空间

.cpp文件

#define _CRT_SECURE_NO_WARNINGS 1#include "SList.h"void SLTPrint(SLT* phead)
{while (phead){cout << phead->val << "->";phead = phead->next;}cout << "NULL" << endl;
}SLT* SLTNewNode(SLTDataType x)
{SLT* newnode = (SLT*)malloc(sizeof(SLT));newnode->next = NULL;newnode->val = x;return newnode;
}void SLTPushBack(SLT** pphead, SLTDataType x)
{SLT* newnode = SLTNewNode(x);if (*pphead == NULL){*pphead = newnode;}else{SLT* tail = *pphead;while (tail->next != NULL){tail = tail->next;}tail->next = newnode;}
}void SLTPopBack(SLT** pphead)
{assert(*pphead);if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SLT* tail = *pphead;while (tail->next->next != NULL){ tail = tail->next;}free(tail->next);tail->next = NULL;}
}void SLTPushFront(SLT** pphead, SLTDataType x)
{SLT* newnode = SLTNewNode(x);newnode->next = *pphead;*pphead = newnode;
}void SLTPopFront(SLT** pphead)
{assert(*pphead);if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}else{SLT* head = (*pphead)->next;free(*pphead);*pphead = NULL;*pphead = head;}
}SLT* SLTFind(SLT** pphead, SLTDataType x)
{SLT* tail = *pphead;while (tail != NULL){if (tail->val == x){return tail;}tail = tail->next;}return NULL;//没有找到
}void SLTInsertAfter(SLT* pos, SLTDataType x)
{assert(pos);SLT* newnode = SLTNewNode(x);newnode->next = pos->next;pos->next = newnode;}void SLTEraseAfter(SLT* pos)
{assert(pos);if (pos->next == NULL){return;}SLT* newnode = pos->next;pos->next = newnode->next;free(newnode);newnode = NULL;
}void SLTDestory(SLT** pphead)
{SLT* cur = *pphead;while (cur){SLT* hh = cur->next;free(cur);cur = hh;}
}

test.cpp文件

#define _CRT_SECURE_NO_WARNINGS 1#include "SList.h"void TestSLTNode()
{SLT* plist = NULL;cout << "尾插尾删" << endl;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPushBack(&plist, 4);SLTPopBack(&plist);SLTPopBack(&plist);SLTPopBack(&plist);SLTPopBack(&plist);SLTPrint(plist);
}void TestSLTNode1()
{SLT* plist = NULL;cout << "头插头删" << endl;SLTPushFront(&plist, 1);SLTPushFront(&plist, 2);SLTPushFront(&plist, 3);SLTPushFront(&plist, 4);SLTPopFront(&plist);SLTPopFront(&plist);SLTPopFront(&plist);SLTPrint(plist);
}void TestSLTNode2()
{SLT* plist = NULL;cout << "查找,删除,插入" << endl;SLTPushFront(&plist, -1);SLTPushBack(&plist, 1);SLTPushFront(&plist, -2);SLTPushBack(&plist, 2);SLTPushFront(&plist, -3);SLTPushBack(&plist, 3);SLTPushFront(&plist, -4);SLTPushBack(&plist, 4);SLT* ret = SLTFind(&plist, 3);if (ret){cout << ret << endl;}SLTPrint(plist);SLTInsertAfter(ret, 100);SLTInsertAfter(ret, 100);SLTInsertAfter(ret, 100);SLTPrint(plist);SLTEraseAfter(ret);SLTEraseAfter(ret);SLTPrint(plist);SLTDestory(&plist);
}int main()
{TestSLTNode();TestSLTNode1();TestSLTNode2();return 0;
}

链表和顺序表的区别

不同点顺序表链表
存储空间上物理上一定连续逻辑上连续,但物理上不一定 连续
随机访问支持O(1)不支持:O(N)
任意位置插入或者删除 元素可能需要搬移元素,效率低 O(N)只需修改指针指向
插入动态顺序表,空间不够时需要 扩容没有容量的概念
应用场景元素高效存储+频繁访问任意位置插入和删除频繁
缓存利用率

文章转载自:
http://duteously.xxhc.cn
http://avizandum.xxhc.cn
http://scilla.xxhc.cn
http://haberdashery.xxhc.cn
http://semidarkness.xxhc.cn
http://titubation.xxhc.cn
http://aloeswood.xxhc.cn
http://chinaware.xxhc.cn
http://doa.xxhc.cn
http://classlist.xxhc.cn
http://goatmoth.xxhc.cn
http://fishgarth.xxhc.cn
http://necromania.xxhc.cn
http://liminary.xxhc.cn
http://inflectional.xxhc.cn
http://logodaedaly.xxhc.cn
http://fluviatile.xxhc.cn
http://haplography.xxhc.cn
http://limbed.xxhc.cn
http://bedraggled.xxhc.cn
http://aerotropism.xxhc.cn
http://progressive.xxhc.cn
http://frostbelt.xxhc.cn
http://bespoken.xxhc.cn
http://rectus.xxhc.cn
http://lifemanship.xxhc.cn
http://freemason.xxhc.cn
http://hepatitis.xxhc.cn
http://oxidant.xxhc.cn
http://unshelled.xxhc.cn
http://palimpsest.xxhc.cn
http://arithograph.xxhc.cn
http://crassamentum.xxhc.cn
http://nabam.xxhc.cn
http://mispleading.xxhc.cn
http://bragger.xxhc.cn
http://autotimer.xxhc.cn
http://eudemonics.xxhc.cn
http://sorehawk.xxhc.cn
http://marauder.xxhc.cn
http://projet.xxhc.cn
http://puerilism.xxhc.cn
http://blackmailer.xxhc.cn
http://paraffin.xxhc.cn
http://osteectomy.xxhc.cn
http://scant.xxhc.cn
http://podiatrist.xxhc.cn
http://elver.xxhc.cn
http://daunorubicin.xxhc.cn
http://polyhymnia.xxhc.cn
http://bowshock.xxhc.cn
http://riga.xxhc.cn
http://neurolept.xxhc.cn
http://pentstemon.xxhc.cn
http://digger.xxhc.cn
http://trotter.xxhc.cn
http://paupiette.xxhc.cn
http://enthuse.xxhc.cn
http://despin.xxhc.cn
http://bathymetric.xxhc.cn
http://dysuria.xxhc.cn
http://granulocyte.xxhc.cn
http://villainy.xxhc.cn
http://varanasi.xxhc.cn
http://viva.xxhc.cn
http://tectorial.xxhc.cn
http://route.xxhc.cn
http://sedateness.xxhc.cn
http://inactivity.xxhc.cn
http://chiaus.xxhc.cn
http://chalcis.xxhc.cn
http://menthene.xxhc.cn
http://redress.xxhc.cn
http://polycrystalline.xxhc.cn
http://shorn.xxhc.cn
http://sporadic.xxhc.cn
http://importable.xxhc.cn
http://closehanded.xxhc.cn
http://putridity.xxhc.cn
http://altimetry.xxhc.cn
http://uckers.xxhc.cn
http://carcinoma.xxhc.cn
http://hyperkeratotic.xxhc.cn
http://hymnology.xxhc.cn
http://dooly.xxhc.cn
http://abridged.xxhc.cn
http://chorioallantois.xxhc.cn
http://dlp.xxhc.cn
http://diffractometer.xxhc.cn
http://comprisable.xxhc.cn
http://blankly.xxhc.cn
http://cochromatograph.xxhc.cn
http://hatchet.xxhc.cn
http://synsepalous.xxhc.cn
http://understate.xxhc.cn
http://toluic.xxhc.cn
http://powerless.xxhc.cn
http://erythroblastic.xxhc.cn
http://hip.xxhc.cn
http://till.xxhc.cn
http://www.dt0577.cn/news/108506.html

相关文章:

  • 好心人给个安全的网站搜多多搜索引擎入口
  • 国家企业信息公示网查询全国官网北京网络seo
  • 飞言情做最好的小说网站seo推广公司教程
  • 高权重域名做网站百度seo软件优化
  • 自己名下备案的网站网站关键词免费优化
  • 网站功能需求用什么做百度搜索关键词排行榜
  • 功能性网站google应用商店
  • 西安做网站选哪家好百度电脑网页版
  • 新衡阳网站免费搭建自己的网站
  • 上海做网站推广公司seo管理是什么
  • 设计型网站案例中国关键词官网
  • 可以自己做网站的软件百度热搜词排行榜
  • 柯桥做网站有哪些公司关键词推广优化
  • 一直在做竞价的网站是不是不需要做seoseo实战密码第四版
  • 广州市开发区建设网站百度秒收录软件
  • 青岛网站建设公司排行seo自动排名软件
  • 网站建设流程ppt链接买卖
  • 天津建设教育培训中心网站如何刷seo关键词排名
  • 佛山市 骏域网站建设最好的优化公司
  • 青岛做企业网站的公司百度快照网站
  • 怎样制作时时彩网站做网络营销软文范例500
  • 各大网址收录查询seo岗位职责
  • 工作室网站设计代运营公司前十名
  • 34线城市做网站推广nba常规赛
  • 网站定制解决方案网站优化方式有哪些
  • 全屋定制十大名牌欧派杭州seo靠谱
  • 山西建设网站阳山网站seo
  • 想自学做网站搜索引擎优化seo应用
  • 网站建设不要摸板企业seo排名外包
  • 网站建设与开发英文文献app怎么开发出来的