您的位置:首页 > 新闻 > 资讯 > 软文推广例子_房地产基础知识300问_百度站长平台链接_seo在线教程

软文推广例子_房地产基础知识300问_百度站长平台链接_seo在线教程

2025/5/24 9:24:43 来源:https://blog.csdn.net/weixin_63997543/article/details/143635609  浏览:    关键词:软文推广例子_房地产基础知识300问_百度站长平台链接_seo在线教程
软文推广例子_房地产基础知识300问_百度站长平台链接_seo在线教程

前面我们讲过单向链表,但是链表的结构非常多。

一、链表的分类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  1. 虽然上面展示了很多链表的结构,但是我们实际上最常用的还是两种结构:单链表和双向链表。
  • 无头单向非循环链表:结构简单,一般不会单独用来存数据。
  • 带头双向循环链表:结构复杂,一般用在单独储存数据。
    v

二、双向链表的实现

  1. 首先创建三个文件
    在这里插入图片描述

头文件List.h:声明函数和定义链表
源文件List.c:用来具体实现函数
测试文件test.c:用来测试工作

1、双向链表的初始化

  • 方法一:直接一个函数生成哨兵位,然后返回哨兵位
LTNode* LTInit()
{LTNode* phead = (LTNode*)malloc(sizeof(LTNode));phead->data = -1;  //这里的值随便定,data无效phead->next = phead->prev = phead;return phead;
}
  • 方法二:传指针,进行加工成哨兵位
void LTInit(LTNode** pphead)
{assert(pphead);*pphead = (LTNode*)malloc(sizeof(LTNode));(*pphead)->data = -1;(*pphead)->next = (*pphead)->prev = *pphead;
}

2、双向链表的销毁

void LTDesTroy(LTNode* phead)
{//创建一个指向头节点的下一个结点的指针LTNode* pcur = phead->next;while (pcur != phead){//创建一个next指针记录位置,避免后续释放的时候找不到下一个结点LTNode* next = pcur->next;free(pcur);pcur = next;}free(phead);phead = NULL;
}

3、双向链表的打印

  • 单向链表的打印靠循环循环的结束标志是pcur == NULL,那双向链表又该怎么打印呀?我们指定双向链表是循环的,如果跟单向链表一样的结束条件会出现死循环的情况,我们会发现前面初始化哨兵位的时候,哨兵位无有效数据,同时循环一轮还是回到哨兵位的位置,那我们就可以将pcur != phead作为循环的结束条件
void LTPrint(LTNode* phead)
{assert(phead);LTNode* pcur = phead->next;while (pcur != phead){printf("%d-> ", pcur->data);pcur = pcur->next;}printf("\n");
}

4、双向链表的尾插

  • 创建一个新节点,想让新节点的prev指针和next指针分别指向phead->prev和phead,在让尾节点的next指针指向newnode和phead->prev指向newnode。
void LTPushBack(LTNode* phead, LTDatatype x)
{assert(phead);//创建一个新节点LTNode* newnode = LTBuyNode(x);newnode->prev = phead->prev; //看图1newnode->next = phead;phead->prev->next = newnode; //图2phead->prev = newnode;
}
  • 图一
    在这里插入图片描述
  • 图二
    在这里插入图片描述

5、双向链表的头插

void LTPushFront(LTNode* phead, LTDatatype x)
{assert(phead);LTNode* newnode = LTBuyNode(x);newnode->next = phead->next; //图一newnode->prev = phead;phead->next->prev = newnode;phead->next = newnode;
}
  • 图一
    在这里插入图片描述
  • 图二

6、双向链表判空

  • 链表的头节点的next指针指向自己的时候说明链表里面没有数据
bool LTEmpty(LTNode* phead)
{assert(phead);return phead->next == phead;
}

7、双向链表尾删

void LTPopBack(LTNode* phead)
{assert(!LTEmpty(phead));LTNode* del = phead->prev;del->prev->next = phead;phead->prev = del->prev;free(del);del = NULL;
}
  • 看下图更好的理解
    在这里插入图片描述

8、双向链表头删

void LTPopFront(LTNode* phead)
{assert(!LTEmpty(phead));LTNode* del = phead->next;del->next->prev = phead;phead->next = del->next;free(del);del = NULL;
}

在这里插入图片描述

9、在pos之后插入数据

void LTInsert(LTNode* pos, LTDatatype x)
{assert(pos);LTNode* newnode = LTBuyNode(x);newnode->next = pos->next; //看红色的箭头newnode->prev = pos;pos->next->prev = newnode; //看粉色的箭头pos->next = newnode;
}

在这里插入图片描述

10、双向链表查找数据

LTNode* LTFind(LTNode* phead, LTDatatype x)
{LTNode* pcur = phead->next;while (pcur != phead){if (pcur->data == x){return pcur;}pcur = pcur->next;}return NULL;
}

11、删除pos位置数据

void LTErase(LTNode* pos) 
{assert(pos);pos->prev->next = pos->next;pos->next->prev = pos->prev;free(pos);pos = NULL;
}

在这里插入图片描述

三、双向链表代码总览

1、List.h

#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>typedef int LTDatatype;
//定义双线链表
typedef struct ListNode
{LTDatatype data;struct ListNode* prev;struct ListNode* next;
}LTNode;//双向链表的初始化
LTNode* LTInit();
//void LTInit(LTNode** pphead);
//链表销毁
//传一级指针,保证接口一致性,但需要手动将实参置为NULL
void LTDesTroy(LTNode* phead);
//创建新节点
LTNode* LTBuyNode(LTDatatype x);
//打印
void LTPrint(LTNode* phead);//尾插
void LTPushBack(LTNode* phead, LTDatatype x);
//头插
void LTPushFront(LTNode* phead, LTDatatype x);
//判断空
bool LTEmpty(LTNode* phead);
//尾删
void LTPopBack(LTNode* phead);
//头删
void LTPopFront(LTNode* phead);
//查找数据
LTNode* LTFind(LTNode* phead, LTDatatype x);
//在pos之后插入数据
void LTInsert(LTNode* pos, LTDatatype x);
//删除pos位置数据
void LTErase(LTNode* pos);

2、List.c

#define  _CRT_SECURE_NO_WARNINGS 1
#include "List.h"//双向链表初始化两种方法
LTNode* LTInit()
{LTNode* phead = (LTNode*)malloc(sizeof(LTNode));phead->data = -1;phead->next = phead->prev = phead;return phead;
}//void LTInit(LTNode** pphead)
//{
//	assert(pphead);
//	*pphead = (LTNode*)malloc(sizeof(LTNode));
//	(*pphead)->data = -1;
//	(*pphead)->next = (*pphead)->prev = *pphead;
//}//链表的销毁
void LTDesTroy(LTNode* phead)
{LTNode* pcur = phead->next;while (pcur != phead){LTNode* next = pcur->next;free(pcur);pcur = next;}free(phead);phead = NULL;
}//打印
void LTPrint(LTNode* phead)
{assert(phead);LTNode* pcur = phead->next;while (pcur != phead){printf("%d-> ", pcur->data);pcur = pcur->next;}printf("\n");
}
//创建一个节点
LTNode* LTBuyNode(LTDatatype x)
{LTNode* node = (LTNode*)malloc(sizeof(LTNode));if (node == NULL)return NULL;node->data = x;node->prev = node->prev = node;return node;
}//尾插
void LTPushBack(LTNode* phead, LTDatatype x)
{assert(phead);//创建一个新节点LTNode* newnode = LTBuyNode(x);newnode->prev = phead->prev;newnode->next = phead;phead->prev->next = newnode;phead->prev = newnode;
}//头插
void LTPushFront(LTNode* phead, LTDatatype x)
{assert(phead);LTNode* newnode = LTBuyNode(x);newnode->next = phead->next;newnode->prev = phead;phead->next->prev = newnode;phead->next = newnode;
}
//判断空
bool LTEmpty(LTNode* phead)
{assert(phead);return phead->next == phead;
}
//尾删
void LTPopBack(LTNode* phead)
{assert(!LTEmpty(phead));LTNode* del = phead->prev;del->prev->next = phead;phead->prev = del->prev;free(del);del = NULL;
}
//头删
void LTPopFront(LTNode* phead)
{assert(!LTEmpty(phead));LTNode* del = phead->next;del->next->prev = phead;phead->next = del->next;free(del);del = NULL;
}//在pos之后插入数据
void LTInsert(LTNode* pos, LTDatatype x)
{assert(pos);LTNode* newnode = LTBuyNode(x);newnode->next = pos->next;newnode->prev = pos;pos->next->prev = newnode;pos->next = newnode;
}//查找数据
LTNode* LTFind(LTNode* phead, LTDatatype x)
{LTNode* pcur = phead->next;while (pcur != phead){if (pcur->data == x){return pcur;}pcur = pcur->next;}return NULL;
}
//删除pos位置数据
void LTErase(LTNode* pos) 
{assert(pos);pos->prev->next = pos->next;pos->next->prev = pos->prev;free(pos);pos = NULL;
}

3、test.c

#define  _CRT_SECURE_NO_WARNINGS 1
#include "List.h"void test()
{//第一种初始化方式LTNode* plist = LTInit();//第二种初始化方式//LTNode* plist = NULL;//LTInit(&plist);//尾插LTPushBack(plist, 1);LTPrint(plist);LTPushBack(plist, 2);LTPrint(plist);LTPushBack(plist, 3);LTPrint(plist);LTPushBack(plist, 4);LTPrint(plist);//链表的销毁/*LTDesTroy(plist);plist = NULL;*///删除pos位置数据/*LTNode* find = LTFind(plist, 2);if (find == NULL){printf("没有找到!");}else{printf("找到了!");}LTErase(find);LTPrint(plist);*///在pos位置之后插入数据/*LTNode* find = LTFind(plist, 2);if (find == NULL){printf("没有找到!");}else{printf("找到了!");}LTInsert(find, 99);LTPrint(plist);*///查找/*LTNode* find = LTFind(plist, 5);if (find == NULL){printf("没有找到!");}else{printf("找到了!");}*///尾删/*LTPopBack(plist);LTPrint(plist);LTPopBack(plist);LTPrint(plist);LTPopBack(plist);LTPrint(plist);LTPopBack(plist);LTPrint(plist);*///头删/*LTPopFront(plist);LTPrint(plist);LTPopFront(plist);LTPrint(plist);LTPopFront(plist);LTPrint(plist);LTPopFront(plist);*///头插/*LTPushFront(plist, 1);LTPrint(plist);LTPushFront(plist, 2);LTPrint(plist);LTPushFront(plist, 3);LTPrint(plist);LTPushFront(plist, 4);LTPrint(plist);*/
}int main()
{test();return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com