【数据结构】顺序表、单双链表的实现

顺序表

顺序表的结构(数组)

//顺序表的初始化
typedef  peoInfo SLDataType;
typedef struct Seqlist    //动态顺序表
{
	SLDataType* arr;
	int size;
	int capacity;
}SL;

顺序表的初始化

arr置为NULL,size 和 capacity 为0

SL sl;  //定义一个顺序表  
//或者SL* ps=(SL*)malloc(sizof(SL));
SLInit(&sl);  //初始化顺序表
void  SLInit(SL* ps)
{
	ps->arr = NULL;
	ps->size = ps->capacity = 0;
}

顺序表实现接口

//顺序表初始化函数
void  SLInit(SL* ps);

//顺序表的销毁
void SLDestory(SL* ps);

//查看空间够不够
void SLCheckCapacity(SL* ps);

//尾插
void SLPushBack(SL* ps, SLDataType x);

//头插
void SLPushFront(SL* ps, SLDataType x);

//用来更快检验程序正确性
void SLPrint(SL* ps);
void SLPrint1(SL s);

//尾删
void SLPopBack(SL* ps);

//头删
void SLPopFront(SL* ps);

//在指定位置插入数据
void SLInsert(SL* ps, int pos, SLDataType x);

//删除指定位置的数据
void SLErase(SL* ps, int pos);

//查找
int SLFind(SL* ps, SLDataType x);

链表

在这里插入图片描述

单链表

单链表的节点结构

单链表是由一个个节点(SLTNode)构成

//定义节点的结构
//数据+指向下一节点的指针
typedef int SLTDataType;
typedef struct SListNode
{
	SLTDataType data;
	struct SListNode* next;
}SLTNode;

单链表的初始化:

无需申请空间,只有给一个phead(先置为NULL),(在尾插phead被确定)

//创立一个链表
	SLTNode* plist = NULL;  //plist相当于phead
	//尾插
	SLTPushBack(&plist, 1);
	SLTPushBack(&plist, 2);
	SLTPushBack(&plist, 3);
	SLTPushBack(&plist, 4);

尾插:分了情况,若phead为NULL,插入的节点地址为phead

void SLTPushBack(SLTNode** pphead, SLTDataType x)//phead链表:头地址    pphead:头地址的地址,为了防止是数的拷贝
{                                                //方法:找到尾指针,改变其next(NULL--->newnode)   
	
	assert(pphead);//pphead不能为空,无法对空指针进行解引用
	//当一级指针为空时,二级指针也能为空
	SLTNode* newnode = SLTBuyNode(x); 
	//空链表和非空链表
	if (*pphead == NULL)
	{
		*pphead = newnode;
	}
	else
	{
		//找尾
		SLTNode* ptail = *pphead;
		while (ptail->next != NULL)
		{
			ptail = ptail->next;
		}  
		//ptail指向的就是尾节点
		ptail->next = newnode;
	}
}

单链表实现中的接口

一旦有了phead,以下函数只是逻辑和遍历的问题。

//链表的打印
void SLTPrint(SLTNode* phead);

//尾插
void SLTPushBack(SLTNode** pphead, SLTDataType x); //插入时就给它创建了新节点

//头插
void SLTPushFront(SLTNode** pphead, SLTDataType x);

//尾删
void SLTPopBack(SLTNode** pphead);

//头删
void SLTPopFront(SLTNode** pphead);

//在指定位置之前插⼊数据
void SLTInsertFront(SLTNode** pphead, SLTNode* pos, SLTDataType x);

//在指定位置之后插⼊数据
void SLTInsertAfter(SLTNode* pos, SLTDataType x);

//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos);

//删除pos之后的节点
void SLTEraseAfter(SLTNode* pos);

//销毁链表
void SListDesTroy(SLTNode** pphead);

注意接口返回值:

//创建新节点    返回新节点指针
SLTNode* SLTBuyNode(SLTDataType x);

//查找        返回找到的节点指针
SLTNode* SLTFind(SLTNode* phead, SLTDataType x);

双链表(双向循环链表)

双链表节点结构

typedef int LTDataType;
typedef struct ListNode
{
	LTDataType data;
	struct ListNode* next;
	struct ListNode* prev;
}LTNode;

链表的初始化

得到一个哨兵位,得到一个phead

void LTInit(LTNode** pphead)
{
	//给双向链表创建一个哨兵位
	(*pphead)= LTBuyNode(-1);
}
LTNode* phead=NULL;
LTInit(&phead);     //phead可使用了
LTNode* LTInit1()
{
	return LTBuyNode(-1);
}
LTNode* phead=LTInit1();

节点申请函数:要传入一个数据,节点的next和prev都指向自己

//申请一个节点
LTNode* LTBuyNode(LTDataType x)
{
	LTNode* node = (LTNode*)malloc(sizeof(LTNode));
	if (node == NULL)
	{
		perror("malloc fail!");
		exit(1);
	}
	node->data=x;
	node->next=node->prev = node;
	return node;
}

双链表实现接口

有了phead,下面的函数实现就是逻辑问题

//创建一个节点
LTNode* buyNode(LTDataType x);

//链表初始化
void LTInit(LTNode** pphead);
LTNode* LTInit1();

//打印链表
void LTPrint(LTNode* phead);

//尾插
void LTPushBack(LTNode* phead, LTDataType x);

//头插
void LTPushFront(LTNode* phead, LTDataType x);

//尾删
void LTPopBack(LTNode* phead);

//头删
void LTPopFront(LTNode* phead);

//在pos位置之后插⼊数据
void LTInsert(LTNode* pos, LTDataType x);

//查找链表
LTNode* LTFind(LTNode* phead, LTDataType x);

//删除pos节点
void LTErase(LTNode* pos);

//销毁链表
void LTDestroy(LTNode* phead);

单双链表的空

单链表:头节点地址为NULL
双链表:只有一个哨兵位

源码

顺序表(含通讯录)的实现
单链表的实现
双链表的实现

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值