1. 程式人生 > >連結串列和順序表(參考stl原始碼,使用c語言實現)

連結串列和順序表(參考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行左右的程式碼運用到一點點演算法,具體參考《資料結構》嚴蔚敏版本。