带头循环双向链表以及顺序表和链表的区别和联系

区别:

1. 无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结
构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。
2. 带头双向循环链表:结构最复杂,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向
循环链表。另外这个结构虽然结构复杂,但是使用代码实现以后会发现结构会带来很多优势,实现反而简单
 

顺序表和链表的区别和联系

顺序表:

空间连续,支持连续访问

中间或前面部分的插入删除时间复杂度为O(n);并且增容的代价比较大

链表:

以节点为字节存储,不支持随机访问

任意位置插入删除时间复杂度都为O(1);插入一个开辟一个空间
 

代码的实现

#include<stdio.h>
#include<stdlib.h>


typedef int LDataType;
//双向节点
typedef struct ListNode
{
	LDataType _data;
	struct ListNode* _prev;
	struct ListNode* _next;
} ListNode;

//双向带头循环链表
typedef struct List
{
	struct ListNode* _head;
	
} List;
void initList(List* lst)
{
	//空的双向带头循环链表
	//构建循环结构 
	//创建头节点
	lst->_head = (struct ListNode*)malloc(sizeof(struct ListNode));
	//循环
	lst->_head->_prev = lst->_head->_next = lst->_head;
}

struct ListNode* creatNode(LDataType val)
{
	struct ListNode* node=(struct ListNode*)malloc(sizeof(struct ListNode));
	node->_data = val;
	node->_next = node->_prev = NULL;
	return node;
}

//尾节点:head->_prev
//尾插(o(1))
void listPushBack(List* lst, LDataType val)
{
	struct ListNode* tail = lst->_head->_prev;
	struct ListNode* newNode = creatNode(val);

	//head  ..... tail  newNode
	tail->_next = newNode;
	newNode->_prev = tail;
	newNode->_next = lst->_head;
	lst->_head->_prev = newNode;

}
//尾删(o(1))
void listPopBack(List* lst)
{
	if (lst->_head->_prev == lst->_head)
		return;//空链表
	struct ListNode* tail = lst->_head->_prev;
	struct ListNode* prev =tail->_prev;

	free(tail);

	prev->_next = lst->_head;
	lst->_head->_prev = prev;
	
}
void printList(List* lst)
{
	struct ListNode* cur = lst->_head->_next;
	while (cur!= lst->_head)
	{
		printf("%d", cur->_data);
		cur =cur->_next;
	}
	printf("\n");
}

//头插:插在头的下一个位置

void listPushFront(List* lst, LDataType val)
{
	struct ListNode* newNode = creatNode(val);

	struct ListNode* next = lst->_head->_next;

	lst->_head->_next = newNode;
	newNode->_prev = lst->_head;
	newNode->_next = next;
	next->_prev = newNode;
}
//头删
void listPopFront(List* lst)
{
	if (lst->_head->_prev == lst->_head)
		return;//空链表
	struct ListNode* next = lst->_head->_next;
	struct ListNode* nextnext = next->_next;
	//head next nextnext
	free(next);
	lst->_head->_next = nextnext;
	nextnext->_prev = lst->_head;
	
}
//头插:insert(head->next,val)
//尾插:insert(head,val)
//新的数据放在当前节点的前面
void listInsert(ListNode* node, LDataType val)
{
	struct ListNode* newNode = creatNode(val);
	struct ListNode* prev = node->_prev;

	node->_prev = newNode;
	newNode->_next = node;

	prev->_next = newNode;
	newNode->_prev = prev;
}
void listErase(ListNode* node)
{
	struct ListNode* prev = node->_prev;
	struct ListNode* next = node->_next;
	free(node);
	next->_prev = prev;
	prev->_next = next;
}
void listDestroy(List* lst)
{
	struct ListNode* cur = lst->_head->_next;
	while (cur != lst->_head)
	{
		struct ListNode* next = cur->_next;
		free(cur);
		cur = next;
	}
        free(lst->_head);
        lst->_head=NULL;
}
void ListFind(List* lst, LDataType x)
{
	while (lst->_head)
	{
		if (lst->_head == x)
		{
			return lst->_head;
		}
		lst->_head = lst->_head->_next;
	}
}

void test()
{
	struct List lst;
	initList(&lst);



	printList(&lst);
}
int main()
{
	test();
	
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值