# 实现无头结点单链表的基本操作函数

## 什么是无头结点链表？？？

#ifndef __SINGLELINKEDLIST_H__
#include<stdio.h>
#include<windows.h>
#include<assert.h>
typedef int DataType;

typedef struct ListNode
{
DataType data;
struct ListNode *next;

}ListNode;

ListNode *InitList(DataType num);//初始化并赋值
void PushBack(ListNode **pplist, DataType num);//尾插
void PrintList(ListNode *plist);//输出
void PopBack(ListNode **pplist);//尾删
void PushFront(ListNode **pplist, DataType num);//头插
void PopFront(ListNode **pplist);//头删
ListNode* Find(ListNode *plist, DataType num);//查找
void Insert(ListNode** pplist, ListNode* pos, DataType x);//插入
void Erase(ListNode** pplist, ListNode* pos);//删除

#endif//__SINGLELINKEDLIST_H__

#include "singlelinkedlist.h"

ListNode *InitList(DataType num)//定义一个新的结点
{
ListNode *node = (ListNode*)malloc(sizeof(ListNode));
node->data = num;
node->next = NULL;
return node;
}
void PushBack(ListNode **pplist, DataType num)//尾插
{

if (*pplist == NULL)//空链表
{
*pplist = InitList(num);//定义一个结点
}
else if ((*pplist)->next == NULL)//只有一个结点
{
(*pplist)->next = InitList(num);
}
else//正常情况(多个结点)
{
ListNode *tail = *pplist;
while (tail->next)
{
tail = tail->next;//依次指向下一个结点，找到为空的尾结点
}
tail->next = InitList(num);//找到以后直接添加一个结点
}
}

void PrintList(ListNode *plist)//打印链表
{
ListNode *tail = plist;
while (tail)
{
printf("%d->", tail->data);
tail = tail->next;
}
printf("NULL");
printf("\n");
}

void PopBack(ListNode **pplist)//尾删
{
if (*pplist == NULL)//空链表
{
return;
}
else if ((*pplist)->next == NULL)//只有一个结点，直接释放
{
free(*pplist);
*pplist = NULL;
}
else
{
ListNode* tail = *pplist;
ListNode* pos = tail;
while (tail->next)//tail指向pos的后一个结点
{
pos = tail;
tail = tail->next;
}
free(tail);//释放最后一个结点就相当于删除了尾结点
tail = NULL;
pos->next = NULL;
}
}

void PushFront(ListNode **pplist, DataType num)//头插
{
if (*pplist == NULL)//空链表
{
*pplist = InitList(num);
}
else
{
ListNode *tmp = InitList(num);//开辟一个新的结点
tmp->next = *pplist;//让它指向原先的开始结点
*pplist = tmp;//pplist依然开始结点
}
}

void PopFront(ListNode **pplist)//头删
{
if (*pplist == NULL)//空链表
{
return;
}
else if ((*pplist)->next == NULL)//只有一个结点
{
*pplist = NULL;
}
else
{
ListNode *tmp = (*pplist)->next;//tmp指向原先头结点指向的下一个位置
free(*pplist);
*pplist = tmp;
}

}

ListNode* Find(ListNode *plist, DataType num)//查找
{
assert(plist);//断言其是否为空链表
while (plist)
{
if (plist->data == num)
{
return plist;
}
plist = plist->next;
}
return NULL;
}

void Insert(ListNode** pplist, ListNode* pos, DataType num)//插入
{
assert(*pplist&&pos);
if (((*pplist)->next == NULL) || (pos == *pplist))
//只有开始结点或者是要插入的正好在开始结点的前面
{
PushFront(pplist, num);
}
else
{
ListNode* tmp = NULL;
ListNode* tail = *pplist;
while (tail->next != pos)
{
tail = tail->next;
}
tmp = InitList(num);
tail->next = tmp;
tmp->next = pos;
}
}

void Erase(ListNode** pplist, ListNode* pos)//删除
{
assert(*pplist&&pos);
if (((*pplist)->next == NULL) || (*pplist == pos))
{
PopFront(pplist);
}
else
{
ListNode* tmp = *pplist;
while (tmp->next != pos)
{
tmp = tmp->next;
}
tmp->next = pos->next;
free(pos);
pos = NULL;
}
}

test.c测试部分

#include "singlelinkedlist.h"

void test()
{
ListNode *list = NULL;
PushBack(&list, 1);
PushBack(&list, 2);
PushBack(&list, 3);
PushBack(&list, 4);
PrintList(list);
PopBack(&list);
PrintList(list);
PopBack(&list);
PrintList(list);
PopBack(&list);
PrintList(list);
PopBack(&list);
PrintList(list);
}

void test1()
{
ListNode *list = NULL;
PushFront(&list, 1);
PushFront(&list, 2);
PushFront(&list, 3);
PushFront(&list, 4);
PushFront(&list, 5);
PrintList(list);
PopFront(&list);
PrintList(list);
PopFront(&list);
PrintList(list);
PopFront(&list);
PrintList(list);
PopFront(&list);
PrintList(list);
PopFront(&list);
PrintList(list);
}

void test2()
{
ListNode *list = NULL;
PushFront(&list, 1);
PushFront(&list, 2);
PushFront(&list, 4);
PushFront(&list, 5);
PushFront(&list, 6);
PrintList(list);
ListNode *ret = Find(list, 2);
//测试使用
/*if (ret != NULL)
{
printf("%p\n", ret);
}
else
{
printf("没有这个值!\n");
}*/
Insert(&list, ret, 3);
PrintList(list);
Erase(&list, ret);
PrintList(list);

}

int main()
{
//test();
//test1();
test2();
system("pause");
return 0;
}

test()测试结果

test1()测试结果

test2()测试结果

11-02

12-01
01-27 9万+
08-05 324
04-17 1653
12-21 1361
11-23 150
09-22 629
04-13 1万+
10-09 575
05-22 2013
02-28 1万+
02-14 399