链表和顺序表(参考stl源码,使用c语言实现)

顺序表

优点:可以随机访问,cpu高速缓存利用率高,不涉及(较少)进行插入和删除操作,应该使用顺序表。

顺序表,不论是动态开辟,还是固定大小,一般放置在栈上,不用程序员手动开辟空间

 

链表:主要运用2种,A单向不带头结点的非循环链表      B双向带头结点的循环链表

特点是,由程序员手动开辟空间,存放在堆上。

频繁的插删时,应该使用链表。

 

以链表代码为例

结构体:

typedef struct Node
{
	struct Node* _pNext;
	DataType _data;
}Node, *PNode;
#include <stdio.h>
#include <assert.h>
#include <malloc.h>

void SListInit(PNode* pHead)
{
	assert(pHead);
	*pHead = NULL;
}
//初始化

void SListPushBack(PNode* pHead, DataType data)//尾插单个元素
{
	PNode pNewNode = NULL;
	assert(pHead);

	pNewNode = BuySListNode(data);
	// 空
	if (NULL == *pHead)
		*pHead = pNewNode;
	else
	{
		// 非空
		PNode pCur = *pHead;
		while (pCur->_pNext)
			pCur = pCur->_pNext;

		pCur->_pNext = pNewNode;
	}
}

void SListPopBack(PNode* pHead)//尾删单个元素
{
	assert(pHead);
	//空
	if (NULL == *pHead)
		return;
	else if (NULL == (*pHead)->_pNext)
	{
		// 只有一个节点
		free(*pHead);
		*pHead = NULL;
	}
	else
	{
		// 多个结点 1--->2--->NULL
		PNode pCur = *pHead;
		while (pCur->_pNext->_pNext)
			pCur = pCur->_pNext;

		free(pCur->_pNext);
		pCur->_pNext = NULL;
	}
}

void SListPushFront(PNode* pHead, DataType data)
{
	PNode pNewNode = NULL;
	assert(pHead);
	pNewNode = BuySListNode(data);
	if (NULL == pNewNode)
		return;

	pNewNode->_pNext = *pHead;
	*pHead = pNewNode;
}

void SListPopFront(PNode* pHead)
{
	PNode pDelNode = NULL;
	assert(pHead);
	if (NULL == *pHead)
		return;

	pDelNode = *pHead;
	*pHead = pDelNode->_pNext;
	free(pDelNode);
}

PNode SListFind(PNode pHead, DataType data)
{
	PNode pCur = pHead;
	while (pCur)
	{
		if (data == pCur->_data)
			return pCur;

		pCur = pCur->_pNext;
	}

	return NULL;
}


void SListInsert(PNode* pHead, PNode pos, DataType data)
{
	PNode pNewNode = NULL;
	assert(pHead);
	if (NULL == *pHead || NULL == pos)
		return;

	pNewNode = BuySListNode(data);
	if (NULL == pNewNode)
		return;

	pNewNode->_pNext = pos->_pNext;
	pos->_pNext = pNewNode;
}

void SListErase(PNode* pHead, PNode pos)
{
	assert(pHead);
	if (NULL == *pHead || NULL == pos)
		return;

	if (pos == *pHead)
		SListPopFront(pHead);
	else
	{
		PNode pCur = *pHead;
		while (pCur && pCur->_pNext != pos)
			pCur = pCur->_pNext;

		if (pCur)
		{
			pCur->_pNext = pos->_pNext;
			free(pos);
		}
	}
}

void SListDestroy(PNode* pHead)
{
	SListClear(pHead);
}

int SListSize(PNode pHead)
{
	int count = 0;
	PNode pCur = pHead;
	while (pCur)
	{
		count++;
		pCur = pCur->_pNext;
	}

	return count;
}

void SListClear(PNode* pHead)
{
	PNode pDelNode = NULL;
	assert(pHead);

	while (*pHead)
	{
		pDelNode = *pHead;
		*pHead = pDelNode->_pNext;
		free(pDelNode);
	}
}

PNode BuySListNode(DataType data)
{
	PNode pNewNode = (PNode)malloc(sizeof(Node));
	if (NULL == pNewNode)
		return NULL;

	pNewNode->_pNext = NULL;
	pNewNode->_data = data;

	return pNewNode;
}

// 找链表中最后一个节点的位置
PNode SListBack(PNode pHead)
{
	PNode pCur = pHead;
	if (NULL == pHead)
		return NULL;

	while (pCur->_pNext)
		pCur = pCur->_pNext;

	return pCur;
}

void PrintList(PNode pHead)
{
	PNode pCur = pHead;
	while (pCur)
	{
		printf("%d---->", pCur->_data);
		pCur = pCur->_pNext;
	}

	printf("NULL\n");
}

代码比较简单,头插和尾插需要3行左右的代码运用到一点点算法,具体参考《数据结构》严蔚敏版本。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值