单链表的基本实现 LinkedList
一种编程思想: 写代码前先总结过程
比如在写头插时,先分析出有3种状态
1.空链表 2.一个节点 3.多个节点
再根据状态写算法步骤,最后总结写代码
LinkedList.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <malloc.h>
typedef int DataType;
typedef struct ListNode
{
DataType data;
struct ListNode *next;
}ListNode;
void PrintList(ListNode *ppList);//打印链表
void Pushback(ListNode **ppList, DataType x);//尾插
void Popback(ListNode **ppList); //尾删
void PushFront(ListNode **ppList, DataType x);//头插
void PopFront(ListNode **ppList); //头删
ListNode* Find(ListNode* pList, DataType x);//查找元素
void Insert(ListNode **ppList, ListNode *pos, DataType x);//在pos前插
void Erase(ListNode** ppList, ListNode* pos); //删除指节点
#include "LinkedList.h"
ListNode *BuyNode(DataType x)//动态开辟
{
ListNode *node = (ListNode*)malloc(sizeof(ListNode));
node->data = x;
node->next = NULL;
return node;
}
void PrintList(ListNode *pList)//打印链表
{
if (pList == NULL)
printf("NULL\n");
else
{
while (pList->next)
{
printf("%d->", pList->data);
pList = pList->next;
}
printf("%d->NULL\n", pList->data);
}
}
void Pushback(ListNode **ppList, DataType x)//尾插
{
//1.空链表
if (*ppList == NULL)
{
*ppList = BuyNode(x);
}
//2.多个节点
else
{
ListNode *tail = *ppList;
while (tail->next)
{
tail = tail->next;
}
tail->next = BuyNode(x);
}
}
void Popback(ListNode **ppList)//尾删
{
//1.空链表
if (*ppList == NULL)
return;
//2.一个节点
else if ((*ppList)->next == NULL)
{
free(*ppList);
*ppList = NULL;
}
//3.多个节点
else
{
ListNode *tail = *ppList;
ListNode *prev = *ppList;
while (tail->next)
{
prev = tail;
tail = tail->next;
}
free(tail);
prev->next = NULL;
}
}
void PushFront(ListNode **ppList, DataType x)//头插
{
//1.空链表
if (*ppList == NULL)
{
*ppList = BuyNode(x);
}
//2.多个节点
else
{
ListNode *tmp = *ppList;
*ppList = BuyNode(x);
(*ppList)->next = tmp;
}
}
void PopFront(ListNode **ppList)//头删
{
//1.空链表
if (*ppList == NULL)
return;
//2.多个节点
else
{
ListNode *tmp = (*ppList)->next;
free(*ppList);
*ppList = tmp;
}
}
ListNode* Find(ListNode* pList, DataType x)//查找元素
{
while (pList)
{
if (pList->data == x)
break;
pList = pList->next;
}
return pList;
}
void Insert(ListNode **ppList, ListNode *pos, DataType x)//在pos前插
{
assert(pos);
assert(ppList);
if (((*ppList)->next == NULL)||(*ppList == pos))
{
PushFront(ppList, x);
}
else
{
ListNode *cur = *ppList;
while (cur->next != pos)
{
cur = cur->next;
}
ListNode *tmp = BuyNode(x);
cur->next = tmp;
tmp->next = pos;
}
}
void Erase(ListNode** ppList, ListNode* pos) //删除指节点
{
assert(ppList && pos);
//该节点为头节点
if (pos == *ppList)
{
PopFront(ppList);
}
//尾节点
else if (pos->next == NULL)
{
Popback(ppList);
}
//中间节点
else
{
ListNode *prev = *ppList;
while (prev->next != pos)
{
prev = prev->next;
}
prev->next = pos->next;
free(pos);
}
}
#include "LinkedList.h"
//Pushxxx Popxxxx
void TestList1()
{
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);
PushFront(&list, 1);//头操作
PushFront(&list, 2);
PushFront(&list, 3);
PushFront(&list, 4);
PrintList(list);
PopFront(&list);
PrintList(list);
PopFront(&list);
PrintList(list);
PopFront(&list);
PrintList(list);
PopFront(&list);
PrintList(list);
}
//Find/Insert/Erase
void TestList2()
{
ListNode *list = NULL;
Pushback(&list, 1);//尾操作
Pushback(&list, 2);
Pushback(&list, 3);
Pushback(&list, 4);
ListNode *pos = Find(list, 1);//查找
Insert(&list, pos, 0);//指定插入
PrintList(list);
pos = Find(list, 4);//指定删除
Erase(&list, pos);
PrintList(list);
}
int main()
{
TestList2();
return 0;
}