基本结构
typedef int DataType;
typedef struct SListNode
{
struct SListNode* _next;
DataType _data;
}SListNode;
链表结构分为两部分,一部分是数据域,存放的是节点的数据部分,另一部分是指针域,保存下一节点的地址
新建节点
和动态顺序表不一样,每次只开辟一个节点的空间,将其节点的指针域赋为空
代码:
SListNode* BuySListNode(DataType x)
{
SListNode *NewNode =(SListNode *) malloc(sizeof(SListNode));
if (NewNode==NULL)
{
perror("申请失败");
exit(EXIT_FAILURE);
}
NewNode->_data = x;
NewNode->_next = NULL;
return NewNode;
}
打印链表
动态顺序表是通过下标来进行访问,而链表是通过指针访问到每一个节点,当某一节点的指针域为空时,说明链表到尾
代码:
void SListPrint(SListNode* pHead)
{
while (pHead != NULL)
{
printf("%d ", pHead->_data);
pHead = pHead->_next;
}
printf("\n");
}
链表的头插(过程如下图)
代码:
void SListPushFront(SListNode** ppHead, DataType x)
{
if ((*ppHead) == NULL)
{
SListNode *cur = BuySListNode(x);
*ppHead = cur;
}
else
{
SListNode *cur = BuySListNode(x);
cur->_next = *ppHead;
*ppHead = cur;
}
}
链表头删(过程如下图)
代码:
void SListPopFront(SListNode** ppHead)
{
if (*ppHead == NULL)
{
printf("list is empty\n");
}
else
{
SListNode *cur = *ppHead;
free(cur);
*ppHead = (*ppHead)->_next;
}
}
尾插(过程与头插想类似在这里不在画图)
代码:
void SListPushBack(SListNode** ppHead, DataType x)
{
assert(ppHead);
SListNode *cur = *ppHead;
if (*ppHead == NULL)
{
*ppHead = BuySListNode(x);
}
else
{
while (cur->_next != NULL)
{
cur = cur->_next;
}
cur->_next = BuySListNode(x);
}
}
尾删
代码:
void SListPopBack(SListNode** ppHead)
{
SListNode *cur = *ppHead;
if (*ppHead == NULL)
{
printf("List is empty\n");
}
else if ((*ppHead)->_next == NULL)
{
free(*ppHead);
*ppHead = NULL;
}
else
{
while (cur->_next->_next != NULL)
{
cur = cur->_next;
}
free(cur->_next);
cur->_next = NULL;
}
}
任意位置插入(指头插)
在这里需要注意几点:
1)链表为空时,只需调用头插即可
2)链表有一个及以上节点时,需注意保存该位置的前一位置,将其与前一位置相连
代码:
void SListInsest(SListNode** ppHead, SListNode* pos, DataType x)
{
assert(*ppHead);
SListNode* prev = *ppHead;//记录pos位置的前一个节点
SListNode* cur = *ppHead;//头结点
if (pos == cur)
{
SListPushFront(ppHead, x);
}
else
{
while (prev->_next != pos)
{
prev = prev->_next;
}
SListNode* NewNode = BuySListNode(x);
NewNode->_next = prev->_next;
prev->_next = NewNode;
}
}
任意位置删除(删除方法类似头插,不在画图)
代码:
void SListErase(SListNode** ppHead, SListNode* pos)
{
if (*ppHead == NULL)
{
printf("list is empty\n");
}
else
{
if (pos == *ppHead)
{
SListNode *cur = *ppHead;
(*ppHead) = (*ppHead)->_next;
free(cur);
}
else if (pos == NULL)
{
SListPopBack(&pos);
}
else
{
SListNode* prev = *ppHead;
while (prev->_next != pos)
{
prev = prev->_next;
}
prev->_next = pos->_next;
free(pos);
}
}
}
下面给出完整代码及测试用例:
SeqList.c:
SListNode* list;
//新建一个节点
SListNode* BuySListNode(DataType x)
{
SListNode *NewNode =(SListNode *) malloc(sizeof(SListNode));
if (NewNode==NULL)
{
perror("申请失败");
exit(EXIT_FAILURE);
}
NewNode->_data = x;
NewNode->_next = NULL;
return NewNode;
}
//打印链表
void SListPrint(SListNode* pHead)
{
while (pHead != NULL)
{
printf("%d ", pHead->_data);
pHead = pHead->_next;
}
printf("\n");
}
//释放节点
void SListDestory(SListNode** ppHead)
{
assert(ppHead);
free(*ppHead);
*ppHead = NULL;
}
//尾插
void SListPushBack(SListNode** ppHead, DataType x)
{
assert(ppHead);
SListNode *cur = *ppHead;
if (*ppHead == NULL)
{
*ppHead = BuySListNode(x);
(*ppHead)->_next = NULL;
}
else
{
while (cur->_next != NULL)
{
cur = cur->_next;
}
cur->_next = BuySListNode(x);
}
}
//尾删
void SListPopBack(SListNode** ppHead)
{
SListNode *cur = *ppHead;
if (*ppHead == NULL)
{
printf("List is empty\n");
}
else if ((*ppHead)->_next == NULL)
{
free(*ppHead);
*ppHead = NULL;
}
else
{
while (cur->_next->_next != NULL)
{
cur = cur->_next;
}
free(cur->_next);
cur->_next = NULL;
}
}
//头插
void SListPushFront(SListNode** ppHead, DataType x)
{
if ((*ppHead) == NULL)
{
SListNode *cur = BuySListNode(x);
*ppHead = cur;
}
else
{
SListNode *cur = BuySListNode(x);
cur->_next = *ppHead;
*ppHead = cur;
}
}
//头删
void SListPopFront(SListNode** ppHead)
{
if (*ppHead == NULL)
{
printf("list is empty\n");
}
else
{
SListNode *cur = *ppHead;
*ppHead = (*ppHead)->_next;
free(cur);
}
}
//任意位置插入
void SListInsest(SListNode** ppHead, SListNode* pos, DataType x)
{
assert(ppHead);
//assert(pos);
SListNode* prev = *ppHead;//记录pos位置的前一个节点
SListNode* cur = *ppHead;//头结点
if (pos == cur)
{
SListPushFront(ppHead, x);
}
else
{
while (prev->_next != pos)
{
prev = prev->_next;
}
SListNode* NewNode = BuySListNode(x);
NewNode->_next = prev->_next;
prev->_next = NewNode;
}
}
//查找
SListNode* SListFind(SListNode* pHead, DataType x)
{
assert(pHead);
SListNode *cur = pHead;
while (cur != NULL)
{
if (cur->_data == x)
{
return cur;
}
cur = cur->_next;
}
return NULL;
}
//任意位置删除
void SListErase(SListNode** ppHead, SListNode* pos)
{
if (*ppHead == NULL)
{
printf("list is empty\n");
}
else
{
if (pos == *ppHead)
{
SListNode *cur = *ppHead;
(*ppHead) = (*ppHead)->_next;
free(cur);
}
else if (pos == NULL)
{
SListPopBack(&pos);
}
else
{
SListNode* prev = *ppHead;
while (prev->_next != pos)
{
prev = prev->_next;
}
prev->_next = pos->_next;
free(pos);
}
}
}
test.c
//测试尾插
void TestSListPushBack()
{
list = NULL;
SListPushBack(&list, 0);
SListPushBack(&list, 1);
SListPushBack(&list, 2);
SListPushBack(&list, 3);
SListPushBack(&list, 4);
SListPushBack(&list, 5);
SListPrint(list);
}
//测试尾删
void TestSListPopBack(SListNode** ppHead)
{
list = NULL;
SListPushBack(&list, 0);
SListPushBack(&list, 1);
SListPushBack(&list, 2);
SListPushBack(&list, 3);
SListPushBack(&list, 4);
SListPushBack(&list, 5);
SListPrint(list);
SListPopBack(&list);
SListPopBack(&list);
SListPopBack(&list);
SListPopBack(&list);
SListPopBack(&list);
SListPopBack(&list);
SListPrint(list);
}
//测试头插
void TestSListPushFront()
{
list = NULL;
SListPushFront(&list, 0);
SListPushFront(&list, 1);
SListPushFront(&list, 2);
SListPushFront(&list, 3);
SListPushFront(&list, 4);
SListPrint(list);
}
//测试头删
void TestSListPopFront()
{
list = NULL;
SListPushFront(&list, 0);
SListPushFront(&list, 1);
SListPushFront(&list, 2);
SListPushFront(&list, 3);
SListPushFront(&list, 4);
SListPrint(list);
SListPopFront(&list);
SListPopFront(&list);
SListPopFront(&list);
SListPopFront(&list);
SListPopFront(&list);
SListPrint(list);
}
//测试查找
void TestSListFind()
{
list = NULL;
SListPushFront(&list, 0);
SListPushFront(&list, 1);
SListPushFront(&list, 2);
SListPushFront(&list, 3);
SListPushFront(&list, 4);
SListNode* cur = SListFind(list, 3);
printf("%d\n", cur->_data);
}
//测试任意位置插入
void TestSListInsest()
{
list = NULL;
SListPushFront(&list, 0);
SListPushFront(&list, 1);
SListPushFront(&list, 2);
SListPushFront(&list, 3);
SListPushFront(&list, 4);
SListPrint(list);
SListNode *ret = SListFind(list, 0);
SListInsest(&list, ret, 78);
ret = SListFind(list, 4);
SListInsest(&list, ret, 78);
ret = SListFind(list, 2);
SListInsest(&list, ret, 78);
SListPrint(list);
}
//测试任意位置删除
void TestSListErase(SListNode** ppHead, SListNode* pos)
{
list = NULL;
SListPushFront(&list, 0);
SListPushFront(&list, 1);
SListPushFront(&list, 2);
SListPushFront(&list, 3);
SListPushFront(&list, 4);
SListPrint(list);
SListNode *ret = SListFind(list, 4);
SListInsest(&list, ret, 23);
SListPrint(list);
ret = SListFind(list, 4);
SListErase(&list, ret);
ret = SListFind(list, 23);
SListErase(&list, ret);
ret = SListFind(list, 0);
SListErase(&list, ret);
SListPrint(list);
}