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

厦门石材网站建设/企业品牌类网站有哪些

厦门石材网站建设,企业品牌类网站有哪些,怎么直接更新wordpress,wordpress获取位置目录 一,线性表 1,什么是线性表 2,线性表的结构 二,链表 1,什么是链表 2,链表的分类 3,单链表的特点 三,链表的实现 1,结构的定义 2,创建一个新结点 3&#…

目录

 一,线性表

        1,什么是线性表

         2,线性表的结构

 二,链表

        1,什么是链表

         2,链表的分类

        3,单链表的特点

三,链表的实现

        1,结构的定义

        2,创建一个新结点

        3,单链表的头插

         4,单链表的尾插

        5,单链表的头删

        6,单链表的尾删

         7,单链表的查找

        8,单链表的在指定位置前插入

         9,单链表的在指定位置后插入

        10,单链表的在指定位置前删除

        11,单链表的在指定位置后删除

四,源码展现

        1,SList.c

        2,SList.h

        3,test_0301.c


 一,线性表

        1,什么是线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列;线性表是一种在实际中广泛使用的数据结构,常见的线性表有:顺序表,链表,栈,队列,字符串...

         2,线性表的结构

线性表在逻辑上是线性结构,通俗来说就是一条连续的直线;但是在物理结构上不一定是连续的,线性表在物理存储上,通常是以数组以及链式结构存储的形式存储的。

 

 注意:

        1,从上图可以看出链式结构在逻辑上是连续的,但在物理上不一定

        2,现实中的节点一般都是从堆上申请出来的

        3,从堆上申请的空间,是按照一定的策略来划分的,两次申请的空间可能是连续的,也可能不是连续的

 二,链表

        1,什么是链表

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

         2,链表的分类

实际中链表的种类多种多样,基本情况组合起来就有8种链表情况之多;本篇文章我们不讨论那么多种就只讨论常用两种:无头单向非循环链表和带头双向循环链表中的无头单向非循环链表,我们简称为:单链表。 

        3,单链表的特点

无头单向非循环链表:结构简单,一般不会用来单独存放数据,实际中更多是作为其他数据结构的子结构,比如哈希桶,图的邻接表等等。另外这种结构在笔试面试中出现很多。

三,链表的实现

        1,结构的定义

#pragma once#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int SLTDataType;    //将数据类型重定义typedef struct SListNode 
{SLTDataType data;    //对应数据类型的指针,指向动态内存开辟的空间struct SListNode* next; //结点//SListNode* data;  不完整这里,要加上struct//SLTNode* data; 函数基本是向上寻找定义
}SLTNode;

如上图代码:我们把int定义成了SLTDataType,此做法是为了方便我们以后用此链表去管理其他不同的数据的类型,这样以后只用修改一个地方即可。

        2,创建一个新结点

//提取节点
SLTNode* BuySLTNode(SLTDataType x) 
{//创建一个节点SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc fail");return;}//初始化newnode->data = x;newnode->next = NULL;return newnode;
}

不止一次创建一个新的节点,我们可以写一个提取节点的函数,直接malloc申请一个新的节点,将数据放在节点中,把指针置空,并返回新节点的地址。

        3,单链表的头插

//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = BuySLTNode(x);newnode->next = *pphead;*pphead = newnode;
}

这里要注意链接的顺序,如果先将头指针指向新结点的头,再将新的结点的尾链接到原来链表的头的话,原来链表的头就找不到了,因为原来链表的头是放在头指针里面的,若先将头指针改了就找不到原来的头了,就链接不上了。

         4,单链表的尾插

//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = BuySLTNode(x);创建一个节点//SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));//if (newnode == NULL) //{//	perror("malloc fail");//	return;//}初始化//newnode->data = x;//newnode->next = NULL;if(*pphead == NULL){*pphead = newnode;}else{//找尾SLTNode* tail = *pphead;while (tail->next != NULL){tail = tail->next;}tail->next = newnode;}
}

这里使用到了二级指针,如果只是单纯的将phead=newnode的化,实际的头结点是没有改变的,因为形参实际上只是实参的一份临时拷贝,尾插函数只是将phead的值改变成了newnode,实际上并没有真正的改变头指针。我们之前学过想要改变值就要传地址,所以这里用到了二级指针。

        5,单链表的头删

//头删
void SLTPopFront(SLTNode** pphead)
{assert(pphead);assert(*pphead);SLTNode* first = *pphead;*pphead = first->next;free(first);first = NULL;
}

这里我们只需要创建一个新的指针变量接收一下*pphead,再把*pphead也就是我们的头部指向刚才的指针变量的下一个那我们的新的头部就改变了,在把我们新创建的变量释放掉,并且置为空,我们就解决了我们的头部删除。

        6,单链表的尾删

//尾删
void SLTPopBack(SLTNode** pphead)
{//先检查pphead一定不能为空assert(pphead);assert(*pphead);//1,只有一个节点if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}//2,多个节点else{SLTNode* tail = *pphead;while (tail->next->next != NULL){tail = tail->next;}free(tail->next);tail->next = NULL;}
}

这里我们需要判断两个情况:一个是链表只有一个结点,还有就是多个结点的情况,只有一个结点很好判断,他的next就是空,就只要把他释放掉并置空就完成了;多个结点的情况我们就需要遍历这个链表,我们这里用了一个新的变量来代替我们的头部变量,目的就是可能会有后续操作还会用到我们的头结点,如果直接用我们的头部结点已经消失了。去判断下一个结点的下一个结点为不为空,不为空tail就去到下一个结点接着判断,直到为空,tail停下的位置就是尾结点,把释放置空掉,我们就达到了一个尾删的操作。

 

         7,单链表的查找

//查找/修改
SLTNode* SLTFind(SLTNode* phead, SLTDataType x) 
{//cur = currentSLTNode* cur = phead;while (cur) {if (cur->data == x) {return cur;}cur = cur->next;}//找不到return NULL;
}

我们只需要遍历我们的链表,如果等于我们的传进来的数字,直接返回就好了,不等于就继续往后找,如果出了循环那就只有一种情况了,那就是找不到,我们直接返回NULL就可以了。

        8,单链表的在指定位置前插入

oid SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x) 
{assert(pphead);assert(pos);if (pos == *pphead) {//头插SLTPushFront(pphead, x);}else {//先找到pos的前一个位置SLTNode* prev = *pphead;while (prev->next != pos) {prev = prev->next;}SLTNode* newnode = BuySLTNode(x);prev->next = newnode;newnode->next = pos;}
}

这里我们也要分为两种情况来进行讨论,如果只用一个结点,我们的pos等于他,那我们在他之前插入不就是头插的操作吗,我们直接调用头插函数就可以了;如果不是一个结点,我们要先找到pos的前一个位置,并且让我们最开始pos的前一个结点指向我们新创建的结点,再让我们的新结点指向pos就可以了。

         9,单链表的在指定位置后插入

//在pos之后插入
void SLTInsertAfter(SLTNode* pos, SLTDataType x) 
{assert(pos);SLTNode* newnode = BuySLTNode(x);newnode->next = pos->next;pos->next = newnode;
}

这个操作是很简单的了,但是一定要注意的是一个先后顺序。切记不要粗心大意。

//在pos之后插入
void SLTInsertAfter(SLTNode* pos, SLTDataType x) 
{assert(pos);SLTNode* newnode = BuySLTNode(x);pos->next = newnode;newnode->next = pos;
}

很多时候一大意就写成这样了哟,各位小伙伴一定要注意。

        10,单链表的在指定位置前删除

//在pos位置处删除
void SLTErase(SLTNode** pphead, SLTNode* pos) 
{assert(pphead);assert(pos);//assert(*pphead);//能断也可以不断if (pos == *pphead) {SLTPopFront(pphead);}else {SLTNode* prev = *pphead;while (prev->next != pos) {prev = prev->next;}prev->next = pos->next;free(pos);//pos = NULL; 形参的改变不改变实参}
}

这里和上面的一样哟,如果只有一个且就是pos,那么就会变成一个头删的操作;这里的pos其实是不需要置空的啊,因为这里形参只是实参的一份临时拷贝,形参的改变不改变实参,一般的这里的置空是交给传参的人。

  

        11,单链表的在指定位置后删除

//在pos后面删除
void SLTEraseAfter(SLTNode* pos) 
{assert(pos);assert(pos->next);//pos->next = pos->next->next;从右往左执行SLTNode* del = pos->next;pos->next = pos->next->next;free(del);del = NULL;
}

很多小伙伴一上来就写了下面这段代码,这样是错误的啊,因为他是从右往左执行的啊,一定不要粗心大意啊;上面的代码才是正确的啊。

//pos->next = pos->next->next;从右往左执行

四,源码展现

        1,SList.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "SList.h"//打印
void SLTPrint(SLTNode* phead)
{//assert(phead);不能断言:链表的结束条件就是为NULLSLTNode* cur = phead;while (cur != NULL) //为空结束{printf("%d->", cur->data);cur = cur->next;//指向下一个节点//cur++;error}printf("NULL\n");//结束标志
}//提取节点
SLTNode* BuySLTNode(SLTDataType x)
{//创建一个节点SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc fail");return;}//初始化newnode->data = x;newnode->next = NULL;return newnode;
}//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = BuySLTNode(x);创建一个节点//SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));//if (newnode == NULL) //{//	perror("malloc fail");//	return;//}初始化//newnode->data = x;//newnode->next = NULL;if(*pphead == NULL){*pphead = newnode;}else{//找尾SLTNode* tail = *pphead;while (tail->next != NULL){tail = tail->next;}tail->next = newnode;}
}//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x)
{assert(pphead);SLTNode* newnode = BuySLTNode(x);newnode->next = *pphead;*pphead = newnode;
}//尾删
void SLTPopBack(SLTNode** pphead)
{//先检查pphead一定不能为空assert(pphead);assert(*pphead);//1,只有一个节点if ((*pphead)->next == NULL){free(*pphead);*pphead = NULL;}//2,多个节点else{SLTNode* tail = *pphead;while (tail->next->next != NULL){tail = tail->next;}free(tail->next);tail->next = NULL;}
}//头删
void SLTPopFront(SLTNode** pphead)
{assert(pphead);assert(*pphead);SLTNode* first = *pphead;*pphead = first->next;free(first);first = NULL;
}//查找/修改
SLTNode* SLTFind(SLTNode* phead, SLTDataType x) 
{//cur = currentSLTNode* cur = phead;while (cur) {if (cur->data == x) {return cur;}cur = cur->next;}//找不到return NULL;
}//在pos之前插入
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x) 
{assert(pphead);assert(pos);if (pos == *pphead) {//头插SLTPushFront(pphead, x);}else {//先找到pos的前一个位置SLTNode* prev = *pphead;while (prev->next != pos) {prev = prev->next;}SLTNode* newnode = BuySLTNode(x);prev->next = newnode;newnode->next = pos;}
}//在pos位置处删除
void SLTErase(SLTNode** pphead, SLTNode* pos) 
{assert(pphead);assert(pos);//assert(*pphead);//能断也可以不断if (pos == *pphead) {SLTPopFront(pphead);}else {SLTNode* prev = *pphead;while (prev->next != pos) {prev = prev->next;}prev->next = pos->next;free(pos);//pos = NULL; 形参的改变不改变实参}
}//最适合的
//在pos之后插入
void SLTInsertAfter(SLTNode* pos, SLTDataType x) 
{assert(pos);SLTNode* newnode = BuySLTNode(x);newnode->next = pos->next;pos->next = newnode;
}
//在pos后面删除
void SLTEraseAfter(SLTNode* pos) 
{assert(pos);assert(pos->next);//pos->next = pos->next->next;从右往左执行SLTNode* del = pos->next;pos->next = pos->next->next;free(del);del = NULL;
}

        2,SList.h

#pragma once#include <stdio.h>
#include <stdlib.h>
#include <assert.h>typedef int SLTDataType;typedef struct SListNode
{SLTDataType data;struct SListNode* next;//SListNode* data;  不完整这里,要加上struct//SLTNode* data; 函数基本是向上寻找定义
}SLTNode;//打印
void SLTPrint(SLTNode* phead);
//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x);
//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x);
//尾删
void SLTPopBack(SLTNode** pphead);
//头删
void SLTPopFront(SLTNode** pphead);
//查找
SLTNode* SLTFind(SLTNode* phead, SLTDataType x);
//pos位置插入
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x);
//pos位置前面删除
void SLTErase(SLTNode** pphead, SLTNode* pos);
//在pos之后插入
void SLTInsertAfter(SLTNode* pos, SLTDataType x);
//在pos后面删除
void SLTEraseAfter(SLTNode* pos);

        3,test_0301.c

#define _CRT_SECURE_NO_WARNINGS 1
#include "SList.h"void TestSList1()
{///*SLTNode* plist = NULL;SLTPushBack(plist, 1);SLTPushBack(plist, 2);SLTPushBack(plist, 3);SLTPushBack(plist, 4);SLTPrint(plist);*/SLTNode* plist = NULL;SLTPushBack(&plist, 1);SLTPushBack(&plist, 2);SLTPushBack(&plist, 3);SLTPushBack(&plist, 4);SLTPrint(plist);
}void TestSList2()
{SLTNode* plist = NULL;SLTPushFront(&plist, 1);SLTPushFront(&plist, 2);SLTPushFront(&plist, 3);SLTPushFront(&plist, 4);SLTPrint(plist);}
void TestSList3()
{SLTNode* plist = NULL;SLTPushFront(&plist, 1);SLTPushFront(&plist, 2);SLTPushFront(&plist, 3);SLTPushFront(&plist, 4);SLTPrint(plist);SLTPopBack(&plist, 1);SLTPrint(plist);SLTPopBack(&plist, 2);SLTPrint(plist);SLTPopBack(&plist, 3);SLTPrint(plist);}
void TestSList4()
{SLTNode* plist = NULL;SLTPushFront(&plist, 1);SLTPushFront(&plist, 2);SLTPushFront(&plist, 3);SLTPushFront(&plist, 4);SLTPrint(plist);/*SLTPopFront(&plist, 4);SLTPrint(plist);SLTPopFront(&plist, 3);SLTPrint(plist);SLTPopFront(&plist, 2);SLTPrint(plist);SLTPopFront(&plist, 1);SLTPrint(plist);*///值为2的结点*2倍SLTNode* ret = SLTFind(&plist, 2);ret->data *= 2;SLTPrint(plist);
}
void TestSList5()
{SLTNode* plist = NULL;SLTPushFront(&plist, 1);SLTPushFront(&plist, 2);SLTPushFront(&plist, 3);SLTPushFront(&plist, 4);SLTPrint(plist);SLTNode* ret = SLTFind(plist, 2);SLTInsert(&plist, ret, 20);SLTPrint(plist);
}
void TestSList6()
{SLTNode* plist = NULL;SLTPushFront(&plist, 1);SLTPushFront(&plist, 2);SLTPushFront(&plist, 3);SLTPushFront(&plist, 4);SLTPrint(plist);SLTNode* ret = SLTFind(plist, 2);SLTErase(&plist, ret);ret = NULL;SLTPrint(plist);
}
void TestSList7()
{SLTNode* plist = NULL;SLTPushFront(&plist, 1);SLTPushFront(&plist, 2);SLTPushFront(&plist, 3);SLTPushFront(&plist, 4);SLTPrint(plist);SLTNode* ret = SLTFind(plist, 2);SLTInsertAfter(ret, 30);SLTPrint(plist);
}
void TestSList8()
{SLTNode* plist = NULL;SLTPushFront(&plist, 1);SLTPushFront(&plist, 2);SLTPushFront(&plist, 3);SLTPushFront(&plist, 4);SLTPrint(plist);SLTNode* ret = SLTFind(plist, 2);SLTEraseAfter(ret);SLTPrint(plist);
}int main()
{//TestSList1();//TestSList2();TestSList3();//TestSList4();//TestSList5();//TestSList6();// TestSList7();//TestSList8();return 0;
}

本篇文章的图都是小编手画的,虽然有点难看,但还是希望得到大家的支持哟!!!

http://www.jmfq.cn/news/4960279.html

相关文章:

  • 公司网站建设需求书/百度广告投放价格表
  • 张家口网站设计/怎么自己做网站
  • 有路由器做网站/seo是什么?
  • 动漫制作专业属于什么大类/seo新闻
  • 龙岩企业网站建设制作/莱阳seo排名
  • 北京建网站 优帮云/非企户百度推广
  • 安徽和城乡建设厅网站/关于营销的最新的新闻
  • 衡阳哪有做网站推广的/烟台网络推广
  • vs做的网站如何/磁力bt种子搜索
  • 安丘做网站的公司/微信怎么引流营销呢
  • 石家庄公司网站如何制作/前端培训费用大概多少
  • 大德通众包网站建设/百度应用商店app下载安装
  • 卖号的正规交易平台/北京seo优化推广
  • wordpress搜索翻页404/win10优化大师是官方的吗
  • 国际电商怎么做/谷歌seo推广服务
  • 个人网站怎么建/青岛排名推广
  • 网站优化应该怎么做/百度竞价怎么收费
  • 网站哪些功能是PHP做的/怎样做一个网页
  • 网站配色 标记色/一手app推广接单平台
  • 公司网站管理制度/搜索引擎优化的主要内容
  • 如何做网站源码/常州网站建设书生商友
  • 上海做网站最专业/网站设计制作公司
  • 昆明做网站建设的公司/奉化首页的关键词优化
  • 网站首页英文/灰色关键词快速排名
  • 郑网站建设/cps推广接单平台
  • 建筑工程网正保/宁波seo行者seo09
  • 丽水网站建设专业的公司/search搜索引擎
  • 网站服务器租用注意事项/加拿大搜索引擎
  • 网站建设员工技能要求/百度竞价推广点击软件奔奔
  • 泰州网站制作哪家好/百度竞价排名查询