上篇博客给出了顺序表的实现,顺序表的优点就是支持随机访问,但是除了在尾部删除插入,在其他位置进行插入删除都要移动大量元素,导致效率低下,因此为了提高插入删除的效率,有了链表这样结构。链表的定义,不再赘述,下面给出单链表的常规操作(增删改查等)的具体实现。
首先定义单链表的结构
typedef int DataType;
typedef struct Node {
DataType data;
struct Node *next;
}Node, *PNode;
将函数的声明放在一个头文件head.h里面
#ifndef _HEAD_H_
#define _HEAD_H_
typedef int DataType;
typedef struct Node {
DataType data;
struct Node *next;
}Node, *PNode;
void InitList(PNode *pHead);//初始化链表
PNode BuyNode(DataType data);//申请节点
void PushBack(PNode *pHead, DataType data);//尾插一个元素
void PopBack(PNode *pHead);//尾删一个元素
void PushFront(PNode *pHead, DataType data);//头插一个元素
void PopFront(PNode *pHead);//头删一个元素
PNode Find(PNode pHead, DataType data);//查找某个元素,返回其位置
void Insert(PNode pos, DataType data);//在置顶位置插入值为data的元素
void Erase(PNode *pHead, PNode pos);//删除链表Pos位置的元素
void Remove(PNode *pHead, DataType data);//删除链表中第一个值为data的元素
void RemoveAll(PNode *pHead, DataType data);//删除链表中所有值为Data的元素
void Destroy(PNode *pHead);//销毁链表
int Empty(PNode pHead);//链表是否为空
int Size(PNode pHead);//求链表中结点的个数
PNode Back(PNode pHead);//返回最后一个节点的位置
void PrintList(PNode pHead);//打印链表的节点
#endif
具体实现如下,给出了部分测试代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "head.h"
void test0();
void test1();
int main()
{
test0();
//test1();
getchar();
return 0;
}
void test0()
{
PNode pHead;
InitList(&pHead);
PushBack(&pHead, 0);
PushBack(&pHead, 1);
PushBack(&pHead, 2);
PushBack(&pHead, 3);
PushBack(&pHead, 5);
PushBack(&pHead, 3);
PrintList(pHead);
Destroy(&pHead);
PrintList(pHead);
}
void test1()
{
PNode pHead;
InitList(&pHead);
PushFront(&pHead, 3);
PushFront(&pHead, 2);
PushFront(&pHead, 1);
PrintList(pHead);
PopFront(&pHead);
PopFront(&pHead);
PrintList(pHead);
PopFront(&pHead);
PrintList(pHead);
}
void InitList(PNode *pHead)
{
*pHead = NULL;
}
PNode BuyNode(DataType data)
{
PNode pNode = (PNode)malloc(sizeof(Node));
if (NULL == pNode) {
printf("out of memory\n");
exit(1);
}
else {
pNode->data = data;
pNode->next = NULL;
return pNode;
}
}
void PushBack(PNode *pHead, DataType data)
{
PNode pNode = BuyNode(data);
if (NULL == *pHead) {
*pHead = pNode;
}
else {
PNode tmpNode = *pHead;
while (tmpNode->next != NULL) {
tmpNode = tmpNode->next;
}
tmpNode->next = pNode;
}
}
void PopBack(PNode *pHead)
{
if (NULL == *pHead) {
return;
}
else if (NULL == (*pHead)->next) {
*pHead = NULL;
free(*pHead);
}
else {
PNode preNode = *pHead;
PNode Node = *pHead;
while (NULL != Node->next) {
preNode = Node;
Node = Node->next;
}
free(Node);
preNode->next = NULL;
}
}
void PushFront(PNode *pHead, DataType data)
{
PNode pNode = BuyNode(data);
if (*pHead == NULL) {
*pHead = pNode;
}
else {
pNode->next = *pHead;
*pHead= pNode;
}
}
void PopFront(PNode *pHead)
{
if (NULL == *pHead) {
return;
}
else if (NULL == (*pHead)->next) {
free(*pHead);
*pHead = NULL;
}
else {
PNode tmpNode = *pHead;
*pHead = (*pHead)->next;
free(tmpNode);
}
}
PNode Find(PNode pHead, DataType data)
{
while (pHead != NULL) {
if (pHead->data == data) {
return pHead;
}
else
pHead = pHead->next;
}
return NULL;
}
void Insert(PNode pos, DataType data)
{
if (NULL == pos)
return;
else {
PNode node = BuyNode(data);
node->next = pos->next;
pos->next = node;
}
}
void Erase(PNode *pHead, PNode pos)
{
if (pos == NULL || *pHead == NULL) {
return;
}
else if (pos == *pHead) {
PNode node = *pHead;
*pHead = (*pHead)->next;
free(node);
}
else {
PNode node = *pHead;
while (node->next != pos) {
node = node->next;
}
node->next = pos->next;
free(pos);
}
}
void Remove(PNode *pHead, DataType data)
{
PNode pos = Find(*pHead, data);
Erase(pHead, pos);
}
void RemoveAll(PNode *pHead, DataType data)
{
int count = 0;
PNode node = *pHead;
while (node != NULL) {
if (node->data == data) {
count++;
}
node = node->next;
}
while (count--) {
Remove(pHead, data);
}
}
void Destroy(PNode *pHead)
{
if (*pHead == NULL)
return;
else {
PNode tmpNode = *pHead;
while (*pHead != NULL) {
*pHead = (*pHead)->next;
free(tmpNode);
tmpNode = *pHead;
}
*pHead = NULL;
}
}
int Empty(PNode pHead)
{
return pHead == NULL;
}
int Size(PNode pHead)
{
int count = 0;
while (pHead != NULL) {
count++;
pHead = pHead->next;
}
return count;
}
PNode Back(PNode pHead)
{
while (NULL != pHead->next) {
pHead = pHead->next;
}
return pHead;
}
void PrintList(PNode pHead)
{
if (NULL == pHead)
printf("the elements in the linklist are empty\n");
else {
printf(" Currently the elements in the linklist: ");
while (pHead != NULL) {
printf("%d ->", pHead->data);
pHead = pHead->next;
}
printf("NULL\n");
}
}