C语言 单链表的实现

上篇博客给出了顺序表的实现,顺序表的优点就是支持随机访问,但是除了在尾部删除插入,在其他位置进行插入删除都要移动大量元素,导致效率低下,因此为了提高插入删除的效率,有了链表这样结构。链表的定义,不再赘述,下面给出单链表的常规操作(增删改查等)的具体实现。

首先定义单链表的结构

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");
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值