連結串列和順序表(參考stl原始碼,使用c語言實現)
阿新 • • 發佈:2018-12-12
順序表
優點:可以隨機訪問,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行左右的程式碼運用到一點點演算法,具體參考《資料結構》嚴蔚敏版本。