码迷,mamicode.com
首页 > 其他好文 > 详细

单链表的基本实现

时间:2016-06-12 02:14:15      阅读:243      评论:0      收藏:0      [点我收藏+]

标签:

单链表是方向单一的链表,即就是只能从前向后访问,不能从后向前访问。这篇文章,我

将整理出单链表的一些基本功能。

1.尾插 2.尾删 3.头插 4.头删5.打印 6.插入7.删除指定元素 8.删除指定元素的全部9.删除指

定位置的元素10.排序(此文先给出基本的冒泡排序,其他排序算法之后再给出)

下边,我就这些功能一个一个进行说明,尽量配图~~(这里的单链表不带头结点)

为了方便大家读以下的代码,我给出结构体的定义。

typedef struct LinkNode
{
	DataType data;
	struct LinkNode *next;
}LinkNode,*pLinkNode;
typedef struct LinkList
{
	LinkNode *pHead;
}LinkList,*pLinkList;


1.尾插:先要找到链表的尾部,然后进行插入。

技术分享

具体实现代码如下:

void PushBackLinkList(pLinkList pList, DataType x)
{
	assert(pList);
	pLinkNode  add = CreatNode(x);
	pLinkNode tmp = pList->pHead;
	if (NULL == pList->pHead)//linklist is empty
	{
		pList->pHead = add;
		add->next = NULL;
		return;
	}
	while (tmp->next)//linklist is not empty
	{
		tmp = tmp->next;
	}
	tmp->next = add;
	add->next = NULL;
	printf("successful  push back\n");
}


2.尾删:顾名思义,找到链表的结尾,将其删除。看图:

技术分享

下边给出代码实现:

void PopBackLinkList(pLinkList pList)
{
	assert(pList);
	if (NULL == pList->pHead)
	{
		printf("linklist is empty.\n");
		return;
	}
	pLinkNode cur = pList->pHead;
	pLinkNode prev = pList->pHead;
	if (NULL == cur->next->next)//linklist only has an element.
	{
		free(cur->next);
		cur->next = NULL;
	}
	else
	{
		while (cur->next)
		{
			prev = cur;
			cur = cur->next;
		}
		free(prev ->next);
		prev->next = NULL;
	}
	printf("successful popback");
}


3.头插:

如果链表是空链表,直接插入就可;有一个元素和有多个元素一样处理。下边图解:

技术分享

下边给出代码实现:

void PushFrontLinkList(pLinkList pList, DataType x)
{
	assert(pList);
	pLinkNode  add = CreatNode(x);
	pLinkNode tmp = pList->pHead;
	if (NULL == pList->pHead)//linklist is empty
	{
		pList->pHead = add;
		add->next = NULL;
		return;
	}
	add->next = tmp;
	pList->pHead = add;
	printf("successful pushfront.\n");
}


4.头删:

如果链表是空,不删除;如果是一个结点,删除后将头指针置为NULL;如果是多个结

点,调整指针就好。图解:

技术分享

下边给出代码实现:

void PopFrontLinkList(pLinkList pList)
{
	assert(pList);
	if (NULL == pList->pHead)
	{
		printf("linklist is empty.\n");
		return;
	}
	pLinkNode tmp = pList->pHead;
	pLinkNode del = pList->pHead;
	if (NULL == tmp->next->next)
	{
		free(tmp->next);
		pList->pHead = NULL;
	}
	else
	{
		del = tmp->next;
		tmp = tmp->next->next;
		free(del);
	}
	printf("successful popfront.\n");
}


5.打印:这个比较简单。

6.指定位置之前插入指定元素:这个我们需要有个find函数来查找指定位置的指针

我们约定:如果是空链表,直接将元素插在链表中。

技术分享

下边给出代码:

void InsertLinkList(pLinkList pList, DataType x, pLinkNode pos)//insert the front of pos
{
	assert(pList);
	pLinkNode p = CreatNode(x);
	pLinkNode tmp = pList->pHead;
	if (NULL == pList->pHead)//check:if linklist is empty,we insert the element in the linklist.
	{
		tmp->next = p;
		p->next = NULL;
		return;
	}
	if (pos == pList->pHead->next)
	{
		PushFrontLinkList(pList, x);
		return;
	}
	while (tmp->next  != pos)
	{
		tmp = tmp->next;
	}
	p->next = tmp->next;
	tmp->next = p;
	printf("successful insertion.\n");
}


7.删除指定元素:

如果链表是空,直接返回;如果链表只有一个元素,如果第一个元素就是指定元素,删

除,然后返回;如果多个元素,找到元素直接删除。

技术分享

代码:

void Remove(pLinkList pList, DataType x)
{
	assert(pList);
	pLinkNode cur = pList->pHead;
	pLinkNode del = pList->pHead;
	pLinkNode prev = pList->pHead;
	if (NULL == pList->pHead)
	{
		printf("linklist is empty.\n");
		return;
	}
	if (cur->next == NULL)//只有一个元素
	{
		if (cur->data == x)
		{
			free(cur->next);
			pList->pHead = NULL;
			return;
		}
	}
	else
	{
		while (cur != NULL)
		{
			if (cur->data == x)
			{
				del = cur;
				pList->pHead = cur->next;
				free(del);
				return;
			}
			cur = cur->next;
			while (cur != NULL)
			{
				if (cur->data == x)
				{
					prev->next = cur->next;
					free(cur);
					return;
				}
				prev = cur;
				cur = cur->next;
			}
		}
	}
	printf("successful remove.\n");
}


8.删除指定元素的全部:

给定元素x,删除链表中所有data为x的元素。如果是空链表,直接返回。先判断链表的

第一个元素。

技术分享

给出代码:

void RemoveAll(pLinkList pList, DataType x)
{
	assert(pList);
	if (NULL == pList->pHead)
	{
		printf("linklist is empty.\n");
		return;
	}
	pLinkNode cur = pList->pHead;
	pLinkNode prev = pList->pHead;
	
	while (cur != NULL)      //判断第一个结点
	{
		if (cur->next == NULL)    //linklist has one element.
		{
			if (cur->data == x)
			{
				free(cur->next);
				pList->pHead = NULL;
				return;
			}
		}
		else if (pList->pHead->data == x) //如果不是一个结点,且第一个结点的数据是x       
		{
			pList->pHead = cur->next;
			free(cur);
			cur = pList->pHead;
		}
		else
			break;
	}
	cur = cur->next;
	prev = pList->pHead;
	while (cur)
	{
		if (cur->data == x)
		{
			prev->next = cur->next;           
			free(cur);
			cur = prev;
		}
		prev = cur;
		cur = cur->next;
	}
	printf("successful removeall.\n");
}


9.删除指定位置的元素:

如果链表是空,直接返回;如果只有一个元素,如果这个元素就是pos位置,删除,返

回;如果多个元素,同样先判断第一个位置,如果是,直接删除,返回,如果不是,继

续向后找。

技术分享

代码:

void Erase(pLinkList pList, pLinkNode pos)
{
	assert(pList);
	if (NULL == pList->pHead)
	{
		printf("linklist is empty.\n");
		return;
	}
	pLinkNode cur = pList->pHead;
	pLinkNode del = pList->pHead;
	pLinkNode prev = pList->pHead;
	if (cur->next == NULL)//如果只有一个元素
	{
		if (pos == cur)
		{                       //第一个结点就是pos位置
			free(pList->pHead);
			pList->pHead = NULL;
		}
		return;
	}
	if (pos == cur)
	{                       //第一个结点就是pos位置
		del = cur;
		pList->pHead = cur->next;
		free(del);
		return;
	}
	cur = cur->next;
	while(cur)
	{ 
		if(cur == pos)
		{
			prev->next = cur->next;
			free(cur);
			return;
		}
		prev = cur;
		cur = cur->next;
	}
}


10.冒泡排序:


技术分享

给出代码:

void BottleSort(pLinkList pList)
{
	assert(pList);
	if (NULL == pList->pHead || NULL == pList -> pHead->next )
	{
		printf("linklist is empty or linklist has one element.\n");
		return;
	}
	pLinkNode front = pList->pHead;
	pLinkNode tail = NULL;
	while (front != tail)
	{
		while (front->next != tail)
		{
			if (front->data > front->next->data)
			{
				DataType tmp = front->data;
				front->data = front->next->data;
				front->next->data = tmp;
			}
			front = front->next;
		}
		tail = front;
		front = pList->pHead;
	}
}


为了方便读者理解,下边给出程序源码:

//LinkList.h
#ifndef __LINKLIST_H__
#define __LINKLIST_H__
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include <assert.h>
#include<stdlib.h>
typedef int DataType;
enum OP
{
	EXIT,
	PUSHBACK,
	POPBACK,
	PUSHFRONT,
	POPFRONT,
	PRINT,
	INSERT,
	REMOVE,
	REMOVEALL,
	ERASE,
	SORT
};
typedef struct LinkNode
{
	DataType data;
	struct LinkNode *next;
}LinkNode,*pLinkNode;
typedef struct LinkList
{
	LinkNode *pHead;
}LinkList,*pLinkList;
void InitLinkList(pLinkList pList);
void DestroyLinkList(pLinkList pList);
void PushBackLinkList(pLinkList pList,DataType x);
void PopBackLinkList(pLinkList pList);
void PushFrontLinkList(pLinkList pList, DataType x);
void PopFrontLinkList(pLinkList pList);
void PrintLinkList(pLinkList pList);
void InsertLinkList(pLinkList pList, DataType x, pLinkNode pos);
void Remove(pLinkList pList, DataType x);
void RemoveAll(pLinkList pList, DataType x);
void Erase(pLinkList pList, pLinkNode pos);
void BottleSort(pLinkList pList);
void menu();
#endif//__LINKLIST_H__


//LinkList.c
#include"LinkList.h"
pLinkNode CreatNode(DataType x)
{
	pLinkNode p = (pLinkNode)malloc(sizeof(LinkNode));
	if (NULL == p)
	{
		printf("out of memory.\n");
		exit(EXIT_FAILURE);
	}
	p->data = x;
	return p;
}
pLinkNode find(pLinkList pList,DataType x)
{
	assert(pList);
	pLinkNode tmp = pList->pHead;
	if (pList->pHead == NULL)
	{
		printf("pList is empty.\n");
	}
	while (tmp->data != x)
	{
		tmp = tmp->next;
	}
	return tmp;
}
void InitLinkList(pLinkList pList)
{
	assert(pList);
	pList ->pHead = NULL;
}
void DestroyLinkList(pLinkList pList)
{
	assert(pList);
	pLinkNode p = pList->pHead;
	pLinkNode del = NULL;
	if (NULL == pList->pHead)
	{
		printf("linklist is empty.\n");
		return;
	}
	while (p)
	{
		pList->pHead = p->next;
		free(p);
		p = pList->pHead;
	}
	pList->pHead = NULL;
}
void PushBackLinkList(pLinkList pList, DataType x)
{
	assert(pList);
	pLinkNode  add = CreatNode(x);
	pLinkNode tmp = pList->pHead;
	if (NULL == pList->pHead)//linklist is empty
	{
		pList->pHead = add;
		add->next = NULL;
		return;
	}
	while (tmp->next)//linklist is not empty
	{
		tmp = tmp->next;
	}
	tmp->next = add;
	add->next = NULL;
	printf("successful  push back\n");
}
void PopBackLinkList(pLinkList pList)
{
	assert(pList);
	if (NULL == pList->pHead)
	{
		printf("linklist is empty.\n");
		return;
	}
	pLinkNode cur = pList->pHead;
	pLinkNode prev = pList->pHead;
	if (NULL == cur->next->next)//linklist only has an element.
	{
		free(cur->next);
		cur->next = NULL;
	}
	else
	{
		while (cur->next)
		{
			prev = cur;
			cur = cur->next;
		}
		free(prev ->next);
		prev->next = NULL;
	}
	printf("successful popback");
}
void PushFrontLinkList(pLinkList pList, DataType x)
{
	assert(pList);
	pLinkNode  add = CreatNode(x);
	pLinkNode tmp = pList->pHead;
	if (NULL == pList->pHead)//linklist is empty
	{
		pList->pHead = add;
		add->next = NULL;
		return;
	}
	add->next = tmp;
	pList->pHead = add;
	printf("successful pushfront.\n");
}
void PopFrontLinkList(pLinkList pList)
{
	assert(pList);
	if (NULL == pList->pHead)
	{
		printf("linklist is empty.\n");
		return;
	}
	pLinkNode tmp = pList->pHead;
	pLinkNode del = pList->pHead;
	if (NULL == tmp->next->next)
	{
		free(tmp->next);
		pList->pHead = NULL;
	}
	else
	{
		del = tmp->next;
		tmp = tmp->next->next;
		free(del);
	}
	printf("successful popfront.\n");
}
void PrintLinkList(pLinkList pList)
{
	assert(pList);
	if (NULL == pList->pHead)
	{
		printf("linklist is empty.\n");
		return;
	}
	pLinkNode tmp = pList->pHead;
	while (tmp)
	{
		printf("%d->",tmp->data);
		tmp = tmp->next;
	}
	printf("over\n");
}
void InsertLinkList(pLinkList pList, DataType x, pLinkNode pos)//insert the front of pos
{
	assert(pList);
	pLinkNode p = CreatNode(x);
	pLinkNode tmp = pList->pHead;
	if (NULL == pList->pHead)//check:if linklist is empty,we insert the element in the linklist.
	{
		tmp->next = p;
		p->next = NULL;
		return;
	}
	if (pos == pList->pHead->next)
	{
		PushFrontLinkList(pList, x);
		return;
	}
	while (tmp->next  != pos)
	{
		tmp = tmp->next;
	}
	p->next = tmp->next;
	tmp->next = p;
	printf("successful insertion.\n");
}
void Remove(pLinkList pList, DataType x)
{
	assert(pList);
	pLinkNode cur = pList->pHead;
	pLinkNode del = pList->pHead;
	pLinkNode prev = pList->pHead;
	if (NULL == pList->pHead)
	{
		printf("linklist is empty.\n");
		return;
	}
	if (cur->next == NULL)//只有一个元素
	{
		if (cur->data == x)
		{
			free(cur->next);
			pList->pHead = NULL;
			return;
		}
	}
	else
	{
		while (cur != NULL)
		{
			if (cur->data == x)
			{
				del = cur;
				pList->pHead = cur->next;
				free(del);
				return;
			}
			cur = cur->next;
			while (cur != NULL)
			{
				if (cur->data == x)
				{
					prev->next = cur->next;
					free(cur);
					return;
				}
				prev = cur;
				cur = cur->next;
			}
		}
	}
	printf("successful remove.\n");
}
void RemoveAll(pLinkList pList, DataType x)
{
	assert(pList);
	if (NULL == pList->pHead)
	{
		printf("linklist is empty.\n");
		return;
	}
	pLinkNode cur = pList->pHead;
	pLinkNode prev = pList->pHead;
	
	while (cur != NULL)      //判断第一个结点
	{
		if (cur->next == NULL)    //linklist has one element.
		{
			if (cur->data == x)
			{
				free(cur->next);
				pList->pHead = NULL;
				return;
			}
		}
		else if (pList->pHead->data == x) //如果不是一个结点,且第一个结点的数据是x       
		{
			pList->pHead = cur->next;
			free(cur);
			cur = pList->pHead;
		}
		else
			break;
	}
	cur = cur->next;
	prev = pList->pHead;
	while (cur)
	{
		if (cur->data == x)
		{
			prev->next = cur->next;           
			free(cur);
			cur = prev;
		}
		prev = cur;
		cur = cur->next;
	}
	printf("successful removeall.\n");
}

void Erase(pLinkList pList, pLinkNode pos)
{
	assert(pList);
	if (NULL == pList->pHead)
	{
		printf("linklist is empty.\n");
		return;
	}
	pLinkNode cur = pList->pHead;
	pLinkNode del = pList->pHead;
	pLinkNode prev = pList->pHead;
	if (cur->next == NULL)//如果只有一个元素
	{
		if (pos == cur)
		{                       //第一个结点就是pos位置
			free(pList->pHead);
			pList->pHead = NULL;
		}
		return;
	}
	if (pos == cur)
	{                       //第一个结点就是pos位置
		del = cur;
		pList->pHead = cur->next;
		free(del);
		return;
	}
	cur = cur->next;
	while(cur)
	{ 
		if(cur == pos)
		{
			prev->next = cur->next;
			free(cur);
			return;
		}
		prev = cur;
		cur = cur->next;
	}
}
void BottleSort(pLinkList pList)
{
	assert(pList);
	if (NULL == pList->pHead || NULL == pList -> pHead->next )
	{
		printf("linklist is empty or linklist has one element.\n");
		return;
	}
	pLinkNode front = pList->pHead;
	pLinkNode tail = NULL;
	while (front != tail)
	{
		while (front->next != tail)
		{
			if (front->data > front->next->data)
			{
				DataType tmp = front->data;
				front->data = front->next->data;
				front->next->data = tmp;
			}
			front = front->next;
		}
		tail = front;
		front = pList->pHead;
	}
}
void menu()
{
	printf("*********1.尾插***************\n");
	printf("*********2.尾删***************\n");
	printf("*********3.头插***************\n");
	printf("*********4.头删***************\n");
	printf("*********5.打印***************\n");
	printf("*********6.插入***************\n");
	printf("*********7.删除指定元素********\n");
	printf("*********8.删除指定的全部*******\n");
	printf("*********9.删除指定位置的元素***\n");
	printf("*********10.排序****************\n");
	printf("*********0.退出*******\n");
}



//test.c
#include"LinkList.h"
void test()
{
	LinkList list;
	pLinkNode pos = NULL;
	InitLinkList(&list);
	int input = 1;
	DataType x = 0;
	DataType y = 0;
	while (input)
	{
		menu();
		printf("please your choice:>");
		scanf("%d",&input);
		switch (input)
		{
		case EXIT:
			DestroyLinkList(&list);
			break;
		case PUSHBACK:
			printf("please input a number of insertion:>");
			scanf("%d",&x);
			PushBackLinkList(&list, x);
			break;
		case POPBACK:
			PopBackLinkList(&list);
			break;
		case PUSHFRONT:
			printf("please input a number of insertion:>");
			scanf("%d", &x);
			PushFrontLinkList(&list, x);
			break;
		case POPFRONT:
			PopFrontLinkList(&list);
			break;
		case PRINT:
			PrintLinkList(&list);
			break;
		case REMOVE:
			printf("please input a number of delete:>");
			scanf("%d", &x);
			Remove(&list, x);
			break;
		case REMOVEALL:
			printf("please input a number of delete:>");
			scanf("%d", &x);
			RemoveAll(&list, x);
			break;
		case ERASE:
			printf("please input a number of delete:>");
			scanf("%d", &x);
			pos = find(&list,x);
			Erase(&list, pos);
			break;
		case SORT:
			BottleSort(&list);
			break;
		case INSERT:
			printf("please input a number of insertion:>");
			scanf("%d", &x);
			printf("please input a number of the data of pos:>");
			scanf("%d", &y);
			pos = find(&list, y);
			InsertLinkList(&list, x, pos);
			break;
		}
	}
}
int main()
{
	test();
	system("pause");
	return 0;
}


就整理这么多,如果有问题,请指出~~

单链表的基本实现

标签:

原文地址:http://blog.csdn.net/peiyao456/article/details/51626853

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!