动态顺序表
linklist.h
#pragma once
#include <stdio.h>
#include <assert.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
typedef int DataType;
typedef struct ListNode
{
struct ListNode* pNext;
DataType _data;
}Node,*PNode;
// 链表的初始化
void SListInit(PNode* pHead);
//创建一个节点
PNode BuyListNode(DataType data);
// 尾插
void SListPushBack(PNode* pHead, DataType data);
// 尾删
void SListPopBack(PNode* pHead);
// 头插
void SListPushFront(PNode* pHead, DataType data);
// 头删
void SListPopFront(PNode* pHead);
// 在链表中查找值为data的元素,找到后返回值为data的结点
PNode SListFind(PNode pHead, DataType data);
// 在pos位置插入值为data的结点
void SListInsert(PNode* pHead, PNode pos, DataType data);
// 删除pos位置额结点
void SListErase(PNode* pHead, PNode pos);
// 计算链表长度
int SListSize(PNode pHead);
// 判断链表是否为空
int SListEmpty(PNode pHead);
// 销毁链表
void SListDestroy(PNode* pHead);
//打印链表
void print(PNode pHead);
linklist.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "linklist.h"
//初始化
void SListInit(PNode* pHead)
{
assert(pHead); //因为pHead是外部实参的地址,外部已经定义,所以地址是一定存在的,不可能为空
//如果为NULL的话一定是出错误了,所以用assert断言来提示
*pHead = NULL;
}
//尾插
void SListPushBack(PNode* pHead, DataType data)
{
assert(pHead);
if(*pHead == NULL)
*pHead = BuyListNode(data);
else
{
PNode pCur = *pHead;
#if 1
while(pCur->pNext) //当本节点的pNext为空是跳出,直接让pCur->pNext指向要插入数据的节点
pCur = pCur->pNext;
#else
PNode pPre = NULL;
while(pCur)
{
pPre = pCur;
pCur = pCur->pNext; //这是不行的,因为pCur最后一定指向空才跳出
//如果为空的话,在下一条语句pCur->pNext就会出错
}
pCur = pPre;
#endif
pCur->pNext = BuyListNode(data); //走到这一步pCur->pNext一定为空要插入节点,应该让pCur->pNext指向新节点
}
}
//尾删
void SListPopBack(PNode* pHead)
{
//三种情况1、0个 2、1个 3、多个
PNode pCur = *pHead;
PNode pPre = NULL;
assert(pHead);
if(*pHead == NULL)
{
printf("无节点可删!\n");
return;
}
else if((*pHead)->pNext == NULL)
{
free(*pHead);
*pHead = NULL;
return;
}
while(pCur->pNext != NULL)
{
pPre = pCur;
pCur = pCur->pNext;
}
free(pCur);
pPre->pNext = NULL;
}
//头插
void SListPushFront(PNode* pHead, DataType data)
{
PNode pCur;
assert(pHead);
if(*pHead == NULL)
{
*pHead = BuyListNode(data);
}
else
pCur = BuyListNode(data);
pCur->pNext = *pHead;
*pHead = pCur;
}
//头删
void SListPopFront(PNode* pHead)
{
PNode next;
assert(pHead);
if(*pHead == NULL)
{
printf("无数据可删!\n");
return;
}
else
{
next = (*pHead)->pNext;
free(*pHead);
*pHead = next;
}
}
//查找
PNode SListFind(PNode pHead, DataType data)
{
if(pHead == NULL)
return NULL;
while(pHead)
{
if(pHead->_data == data)
return pHead;
pHead = pHead->pNext;
}
return NULL;
}
// 在pos位置插入值为data的结点
void SListInsert(PNode* pHead, PNode pos, DataType data)
{
assert(pHead);
if(*pHead == NULL || pos == NULL)
return ;
if(*pHead == pos)
{
PNode pCur =BuyListNode(data);
pCur->pNext = *pHead;
*pHead = pCur;
}
else
{
PNode pCur = *pHead;
PNode pPre = NULL;
while( pCur != pos && pCur )
{
pPre = pCur;
pCur = pCur->pNext;
}
if(pCur)
{
PNode pNew = BuyListNode(data);
pNew->pNext = pCur;
pPre->pNext = pNew;
}
}
}
// 删除pos位置额结点
void SListErase(PNode* pHead, PNode pos)
{
assert(pHead);
if(*pHead == NULL || pos == NULL)
return;
else if(pos == *pHead)
{
PNode pDel = *pHead;
*pHead = (*pHead)->pNext;
free(pDel);
}
else
{
PNode pCur = *pHead;
PNode pPre = NULL;
while(pCur!=pos && pCur)
{
pPre = pCur;
pCur = pCur->pNext;
}
if(pCur)
{
pPre->pNext = pCur->pNext;
free(pCur);
}
}
}
//计算链表长度
int SListSize(PNode pHead)
{
int count = 0;
if(pHead == NULL)
return 0;
else
{
while(pHead)
{
count++;
pHead = pHead->pNext;
}
}
return count;
}
//判断为空
int SListEmpty(PNode pHead)
{
return pHead?1:0;
//if(pHead == NULL)
//{
// printf("链表为空!\n");
// return 0;
//}
//else
// printf("链表不为空!\n");
//return 0;
}
//清空链表
void SListDestroy(PNode* pHead)
{
PNode pCur = *pHead;
PNode pNext = NULL;
assert(pHead);
if(*pHead == NULL)
return;
else
{
*pHead = NULL;
while(pCur)
{
pNext = pCur->pNext;
free(pCur);
pCur = pNext;
}
}
}
//创建一个节点
PNode BuyListNode(DataType data)
{
PNode pNewNode = (PNode)malloc(sizeof(Node));
if(pNewNode == NULL)
{
assert(0);
return NULL;
}
pNewNode->_data = data;
pNewNode->pNext = NULL;
return pNewNode;
}
//打印链表
void print(PNode pHead)
{
if(pHead == NULL)
{
printf("NULL\n");
return;
}
while(pHead)
{
printf("%d->",pHead->_data);
pHead = pHead->pNext;
}
printf("NULL\n");
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "linklist.h"
void test();
void test1();
int main()
{
test();
return 0;
}
//测试
//查找、任意插、任意删、判空、销毁
void test1()
{
PNode pHead = NULL;
SListInit(&pHead); //初始化
SListPushBack(&pHead,54); //尾插
SListPushBack(&pHead,465);
SListPushBack(&pHead,8);
SListPushBack(&pHead,78);
printf("%p\n",SListFind(pHead,465)); //打印465的节点(465的存储地址)
printf("%d\n",SListFind(pHead,465)->_data); //打印465的节点的内容
SListInsert(&pHead,SListFind(pHead,54),100);//在54的位置插入一个数据100
print(pHead);
SListErase(&pHead,SListFind(pHead,100)); //删除链表中数据为100的节点
print(pHead);
printf("节点的个数为:%d\n",SListSize(pHead)); //打印节点的个数
printf("%d\n",SListEmpty(pHead)); //判断链表是否为空打印1不为空0为空
SListDestroy(&pHead); //销毁链表
print(pHead);
}
//测试
//头删、头插、尾删、尾插
void test()
{
PNode pHead = NULL; //这里直接赋值为空
SListInit(&pHead); //初始化
SListPushBack(&pHead,3); //尾插
SListPushBack(&pHead,4); //尾插
print(pHead);
SListPushFront(&pHead,6); //头插
SListPushFront(&pHead,34);
SListPushFront(&pHead,54);
print(pHead);
SListPopBack(&pHead); //尾删
SListPopFront(&pHead); //头删
print(pHead);
SListDestroy(&pHead);
}