顺序表
优点:可以随机访问,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行左右的代码运用到一点点算法,具体参考《数据结构》严蔚敏版本。