【数据结构】单链表

单链表的基本实现 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); //删除指节点


LinkedList.cpp

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


test.cpp

#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;
}




猜你喜欢

转载自blog.csdn.net/qq_32672481/article/details/72972207