1、顺序表
1.1、顺序表元素创建
typedef int SLDatatype; //通过宏定义将int定义为SLDatatype,便于后期更改维护
typedef struct SeqList
{
SLDatatype* a;
int size; //存储的有效数据的个数
int capacity; //容量
}SL;
1.2、初始化
void SLInit(SL* psl)
{
psl->a=(SLDatatype*)malloc(sizeof(SLDatatype)*4); //开辟4个元素大小的空间
if (psl->a == NULL) //判断
{
perror("malloc fail");
return;
}
psl->size=0; //数量
psl->capacity=4; //容量
}
1.3、销毁
void SLDestroy(SL* psl)
{
free(psl->a);
psl->a = NULL;
psl->size = 0;
psl->capacity = 0;
}
1.4、打印
void SLPrint(SL* psl)
{
int i = 0;
for (i=0;i<psl->size;i++)
{
printf("%d ", psl->a[i]);
}
printf("\n");
}
1.5、检查容量
void SLCheckCapacity(SL* psl)
{
if (psl->size == psl->capacity)
{
SLDatatype* tmp = (SLDatatype*)realloc(psl->a, sizeof(SLDatatype) * psl->capacity * 2);
if (tmp == NULL)
{
perror("realloc fail");
return;
}
psl->a = tmp;
psl->capacity *= 2;
}
}
1.6、尾插
void SLPushBack(SL* psl, SLDatatype x)
{
SLCheckCapacity(psl);
psl->a[psl->size] = x;
psl->size++;
}
1.7、头插
void SLPushFront(SL* psl, SLDatatype x)
{
SLCheckCapacity(psl);
//挪动数据
int end = psl->size - 1;
while (end)
{
psl->a[end + 1] = psl->a[end];
--end;
}
psl->a[0] = x;
psl->size++;
}
1.8、尾删
void SLPopBack(SL* psl)
{
assert(psl->size > 0);
psl->size--;
}
1.9、头插
void SLPopFront(SL* psl)
{
assert(psl->size > 0);
int start = 1;
while (start < psl->size)
{
psl->a[start - 1] = psl->a[start];
start++;
}
psl->size--;
}
1.10、在指定位置之前插入
void SLInsert(SL* psl, int pos, SLDatatype x)
{
SLCheckCapacity(psl);
assert(pos >= 0 && pos <= psl->size);
int end = psl->size;
while (end>pos)
{
psl->a[ end ] = psl->a[ end-1 ];
end--;
}
psl->a[pos] = x;
psl->size++;
}
1.11、擦除指定位置
void SLErase(SL* psl, int pos)
{
assert(pos > 0 && pos < psl->size);
int start = pos-1;
while (start<psl->size)
{
psl->a[start] = psl->a[start + 1];
start++;
}
psl->size--;
}
2、单链表
2.1、节点创建
typedef int SLTDataType;
typedef struct SListNode
{
SLTDataType data;
struct SListNode* next;
}SLTNode;
2.2、申请节点
SLTNode* BuyLTNode(SLTDataType x) //返回值为结构体指针的函数
{
SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));
if (newnode == NULL)
{
perror("malloc fail");
return;
}
newnode->data = x;
newnode->next = NULL;
return newnode;
}
2.3、头插
void SLPushFront(SLTNode** pphead, SLTDataType x)
{
assert(pphead);
SLTNode* newnode = BuyLTNode(x);
newnode -> next = *pphead;
*pphead = newnode;
}
2.4、尾插
void SLPushBack(SLTNode** pphead, SLTDataType x)
{
assert(pphead);
SLTNode* newnode = BuyLTNode(x);
if (*pphead == NULL)
{
*pphead = newnode;
}
else
{
SLTNode* tail = *pphead;
while (tail->next != NULL)
{
tail = tail->next;
}
tail->next = newnode;
}
}
2.5、头删
void SLPopFront(SLTNode** pphead)
{
assert(pphead);
assert(*pphead);
SLTNode* del = *pphead;
*pphead = (*pphead)->next;
free(del);
}
2.6、尾删
void SLPopBack(SLTNode** pphead)
{
assert(pphead);
assert(*pphead);
if ((*pphead)->next == NULL)
{
free(*pphead);
*pphead = NULL;
}
else
{
SLTNode* tail = *pphead;
while (tail->next->next)
{
tail = tail->next;
}
free(tail->next);
tail->next = NULL;
}
}
2.7、查找
SLTNode* STFind(SLTNode* phead, SLTDataType x)
{
SLTNode* cur = phead;
while (cur)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
2.8、在pos前插入
void SLInsert(SLTNode** pphead, SLTNode* pos, SLTDataType x)
{
assert(pphead);
assert(pos);
if (*pphead == pos)
{
SLPushFront(pphead, x);
}
else
{
SLTNode* cur = *pphead;
while (cur->next != pos)
{
cur = cur->next;
}
SLTNode* newnode = BuyLTNode(x);
newnode->next = pos;
cur->next = newnode;
}
}
2.9、在pos后插入
void SLInsertAfter(SLTNode* pos, SLTDataType x)
{
assert(pos);
SLTNode* newnode = BuyLTNode(x);
newnode->next = pos->next;
pos->next = newnode;
}
2.10、删除pos位置
void SLErase(SLTNode** pphead, SLTNode* pos)
{
assert(pphead);
assert(pos);
if (pos == *pphead)
{
SLPopFront(pphead);
}
else
{
SLTNode* prev = *pphead;
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = pos->next;
free(pos);
}
}
2.11、删除pos后的值
void SLTEraseAfter(SLTNode* pos)
{
assert(pos);
assert(pos->next);
SLTNode* next = pos->next;
pos->next = next->next;
free(next);
}
2.12、打印
void SLTPrint(SLTNode* phead)
{
SLTNode* cur = phead;
while (cur != NULL)
{
printf("%d->", cur->data);
cur = cur->next;
}
printf("NULL\n");
}
2.12、销毁
void SLDestory(SLTNode** pphead)
{
assert(pphead);
SLTNode* cur = *pphead;
while (cur)
{
SLTNode* next = cur->next;
free(cur);
cur = next;
}
*pphead = NULL;
}
3、双向链表
3.1、创建节点
typedef int LTDataType;
typedef struct ListNode
{
struct ListNode* next;
struct ListNode* prev;
LTDataType data;
}LTNode;
3.2、申请节点
LTNode* BuyLTNode(LTDataType x)
{
LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));
if (newnode == NULL)
{
perror("malloc fail");
return NULL;
}
newnode->data = x;
newnode->prev = NULL;
newnode->next = NULL;
return newnode;
}
3.3、初始化
LTNode* LTInit()
{
LTNode* phead = BuyLTNode(-1);
phead->next = phead;
phead->prev = phead;
return phead;
}
3.4、打印
void LTPrint(LTNode* phead)
{
assert(phead);
printf("哨兵位<==>");
LTNode* cur = phead->next;
while (cur != phead)
{
printf("%d<==>", cur->data);
cur = cur->next;
}
printf("\n");
}
3.5、检查是否为空
bool LTEmpty(LTNode* phead)
{
assert(phead);
return phead->next == phead;
}
3.6、查找
LTNode* LTFind(LTNode* phead, LTDataType x)
{
assert(phead);
//标记第一个节点
LTNode* cur = phead->next;
//找尾并比对data的值
while (cur != phead)
{
if (cur->data == x)
{
return cur;
}
cur = cur->next;
}
return NULL;
}
3.7、头插
void LTPushFront(LTNode* phead, LTDataType x)
{
assert(phead);
/*
LTNode* newnode = BuyLTNode(x);
//phead的后一位链接到newnode的后面
newnode->next = phead->next;
phead->next->prev = newnode;
//newnode链接到phead后面
phead->next = newnode;
newnode->prev = phead;*/
LTInsert(phead->next, x);//可将注释掉的部分直接改为使用LTInsert函数插入在phead->next之前
}
3.8、尾插
void LTPushBack(LTNode* phead, LTDataType x)
{
assert(phead);
/*
LTNode* tail = phead->prev;
LTNode* newnode = BuyLTNode(x);
tail->next = newnode;
newnode->prev = tail;
newnode->next = phead;
phead->prev = newnode;*/
LTInsert(phead, x);//可将注释部分改为使用LTInsert函数插入在哨兵位之前
}
3.9、头删
void LTPopFront(LTNode* phead)
{
assert(phead);
assert(!LTEmpty(phead));
/*
LTNode* first = phead->next;
LTNode* second = first->next;
//重新链接
phead->next = second;
second->prev = phead;
//释放头节点
free(first);*/
LTErase(phead->next);//使用删除函数LTErase删除第一个节点
}
3.10、尾删
void LTPopBack(LTNode* phead)
{
assert(phead);
assert(!LTEmpty(phead));
/*
LTNode* tail = phead->prev;
LTNode* tailPrev = tail->prev;
//free尾节点
free(tail);
//重新链接
tailPrev->next = phead;
phead->prev = tailPrev;*/
LTErase(phead->prev);//使用删除函数LTErase删除最后一个节点
}
3.11、在pos位置插入
void LTInsert(LTNode* pos, LTDataType x)
{
assert(pos);
//创建一个节点指示pos之前的节点
LTNode* prev = pos->prev;
LTNode* newnode = BuyLTNode(x);
//重新链接
prev->next = newnode;
newnode->prev = prev;
newnode->next = pos;
pos->prev = newnode;
}
3.12、删除
void LTErase(LTNode* pos)
{
assert(pos);
//创建节点标记Pos前后的节点
LTNode* posPrve = pos->prev;
LTNode* posNext = pos->next;
//重新链接
posPrve->next = posNext;
posNext->prev = posPrve;
free(pos);
}
3.13、销毁
void Destory(LTNode* phead)
{
assert(phead);
LTNode* cur = phead->next;
while (cur != phead)
{
LTNode* next = cur->next;
free(cur);
cur = next;
}
free(phead);
}