单链表:单链表是线性表链式存储的一种形式,其中的结点一般含有两个域,一个是存放数据信息的数据域(Data),另一个是指向该结点的后继结点存放地址的指针域(Next),一个单链表必须有一个首指针指向单链表中的第一个结点。
单链表的结构如下所示:
typedef int DataType;
typedef struct Node
{
DataType data; //存放数据信息的数据域
struct Node* next; //后继结点存放地址的指针域
}Node, *pNode,*pList;
1,如下是单链表主要基本实现,我将实现的基本接口统一放入一个LinkList.h的头文件中:
#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<malloc.h>
typedef int DataType;
typedef struct Node
{
DataType data;
struct Node* next;
}Node, *pNode, *pList;
void InitLinkList(pList* pplist);//链表的初始化
pNode BuyNode(DataType d);//结点的获取
void DestroyLinkList(pList* pplist);//链表的销毁
void PrintLinkList(pList plist);//链表的打印
void PushBack(pList* pplist, DataType d);//将数据尾插到链表中
void PushFront(pList* pplist, DataType d);//将数据头插到链表中
void PopFront(pList* pplist);//删除头结点
pNode Find(pList plist, DataType d);//查找一个数是否在链表中
void Insert(pList* pplist, pNode pos, DataType d);//在链表某一个位置插入一个数(位置之后插入)
void Erase(pList* pplist, pNode pos);//指定位置删除
void LinklistClear(pList *pplist);//清空链表
int LinklistSize(pList plist);//求链表的长度
2.然后将主函数放入到一个LinkList.c中:
#include"LinkList.h"
void InitLinkList(pList *pplist) //链表的初始化
{
assert(pplist); //断言,判断链表是否存在,下同
*pplist = NULL;
}
pNode BuyNode(DataType d) //结点的获取
{
pNode newnode = (pNode)malloc(sizeof(Node));
if (NULL == newnode)
return NULL;
newnode->next = NULL;
newnode->data = d;
return newnode;
}
void PushBack(pList* pplist, DataType d)//尾插法,将一个结点尾插到链表中
{
pList newnode = NULL;
assert(pplist);
newnode = BuyNode(d);
if (NULL == *pplist)//空链表
*pplist = newnode;
else
{
pList pCur = *pplist;//非空链表
while (pCur->next)
pCur = pCur->next;
pCur->next = newnode;
}
}
void PushFront(pList* pplist, DataType d)//头插法,将一个结点头插到链表中
{
pList newnode = NULL;
assert(pplist);
newnode = BuyNode(d);
if (NULL == newnode)
return;
newnode->next=*pplist;
*pplist = newnode;
}
void PopFront(pList* pplist)//删除头结点
{
pList pnode= NULL;
assert(pplist);
if (NULL == *pplist)//链表为空,不拿删除
return;
pnode= *pplist;
*pplist = pnode->next;
free(pnode);
pnode = NULL;
}
void DestroyLinkList(pList* pplist)//链表的销毁
{
LinklistClear(pplist);
}
pNode Find(pList plist, DataType d)//查找一个结点是否在链表存在
{
pList pCur = plist;
while (pCur)
{
if (d == pCur->data)
return pCur;
pCur = pCur->next;
}
return NULL;
}
void Insert(pList* pplist, pNode pos, DataType d)//指定位置插入,后插
{
pList newnode = NULL;
assert(pplist);
if (NULL == *pplist || NULL == pos)//链表为空和给定结点不存在
return;
newnode =BuyNode(d);
if (NULL == newnode)//开辟结点失败
return;
//多个结点
newnode->next = pos->next;
pos->next = newnode;
}
void Erase(pList* pplist, pNode pos)//指定删除结点
{
pList pCur = NULL;
assert(pplist);
if (NULL == *pplist || NULL == pos)//判断链表是否为空和给定节点存不存在
return;
if (pos == *pplist)//如果只有一个节点,直接用头删
PopFront(pplist);//调用头删函数
/*else//有多个节点
{
pCur = *pplist;
while (pCur&&pCur->next != pos)
pCur = pCur->next;
if (pCur)//如果不为空,则执行下面
{
pCur->next = pos->next;
free(pos);
// }*///难点
// }
}
void LinklistClear(pList *pplist)//清空结点
{
pList Delnode = NULL;
assert(pplist);
while (*pplist)
{
Delnode = *pplist;
Delnode = Delnode->next;
free(Delnode);
}
}
int LinklistSize(pList plist)//计算链表中结点的个数
{
pList pCur = plist;
int count = 0;
while (pCur)
{
count++;
pCur = pCur->next;
}
return count;
}
void PrintLinkList(pList plist)//打印链表
{
pList pCur = plist;
while (pCur)
{
printf("%d->", pCur->data);
pCur = pCur->next;
}
printf("NULL\n");
}
TestLinklist2()
{
pNode plist;
InitLinkList(&plist);
PushFront(&plist, 1);
PushFront(&plist, 2);
PushFront(&plist, 3);
PushFront(&plist, 4);
PushFront(&plist, 5);
PrintLinkList(plist);
//Find(plist,3);
/*PopFront(&plist);
PopFront(&plist);
PopFront(&plist);
PopFront(&plist);
PrintLinkList(plist);*/
}
TestLinklist1()
{
pNode plist,pos;
InitLinkList(&plist);
PushBack(&plist, 1);
PushBack(&plist, 2);
PushBack(&plist, 3);
PushBack(&plist, 4);
PushBack(&plist, 5);
PrintLinkList(plist);
pos=Find(plist, 3);
if (pos)
Insert(&plist, pos, 6);
PrintLinkList(plist);
Erase(&plist, pos);//删除结点
PrintLinkList(plist);
printf("size=%d" ,LinklistSize(plist));
LinklistClear(&plist);
printf("size=%d", LinklistSize(plist));
DestroyLinkList(&plist);
}
int main()
{
//TestLinklist1();
//TestLinklist2();
return 0;
}
以上主要就是不带头单链表的基本实现,带头单链表基本实现与不带头单链表实现基本相同,带头单链表在初始化是,获取一个结点就可以了。。。