1. 程式人生 > >無頭單鏈表

無頭單鏈表

一、連結串列概念

1、連結串列:一種鏈式儲存的線性表,用一組地址任意的儲存單元存放線性表的資料元素,稱儲存單元為一個節點

2、連結串列有單鏈表、雙鏈表和雙向迴圈連結串列,每種連結串列都有無頭和帶頭兩種,帶頭就是頭結點不存放資料元素

二、原始碼

1、linklist.h

#ifndef __LINKLIST_H__ 
#define __LINKLIST_H__ 

#include "stdio.h" 
#include "assert.h"
#include "string.h"
#include "malloc.h"
#include "stdlib.h"

typedef int DataType;

typedef struct Node
{
	DataType data;
	struct Node* next;
}List, *pList;

void InitLinkList(pList* pplist);
pList BuyNode(DataType d);
void DestroyLinkList(pList* pplist);
void PushBack(pList* pplist, DataType d);
void PopBack(pList* pplist);
void PushFront(pList* pplist, DataType d);
void PopFront(pList* pplist);
pList Find(pList plist, DataType d);
void Insert(pList* pplist, pList pos, DataType d);
void Erase(pList* pplist, pList pos);
void Remove(pList* pplist, DataType d);
void RemoveAll(pList* pplist, DataType d);
void PrintLinkList(pList plist);
int GetListLength(pList plist);
void PrintTailToHead(pList plist);

#endif

2、linklist.c

#include "linklist.h"
//初始化
void InitLinkList(pList* pplist)
{
	assert(pplist);
	*pplist = NULL;
}
//建立結點
pList BuyNode(DataType d)
{
	pList node = (pList)malloc(sizeof(List));
	node->data = d;
	node->next = NULL;
	return node;
}
//清除連結串列
void DestroyLinkList(pList* pplist)
{
	assert(pplist);
	while ((*pplist)!=NULL)
	{
		PopBack(pplist);
	}
}
//尾插
void PushBack(pList* pplist, DataType d)
{
	
	if (*pplist == NULL)
		*pplist = BuyNode(d);
	else
	{
		pList p = *pplist;
		while (p->next)
		{
			p = p->next;
		}
		p->next = BuyNode(d);
	}
}
//尾刪
void PopBack(pList* pplist)
{
	assert(pplist);
	if (*pplist == NULL)
		return;
	if ((*pplist)->next == NULL)
	{
		free(*pplist);
		*pplist = NULL;
	}
	else
	{
		pList tmp = *pplist;
		while (tmp->next->next)
		{
			tmp = tmp->next;
		}
		free(tmp->next);
		tmp->next = NULL;
	}
}
//頭插
void PushFront(pList* pplist, DataType d)
{
	assert(pplist);
	pList p = BuyNode(d);
	p->next = *pplist;
	*pplist = p;
}
//頭刪
void PopFront(pList* pplist)
{
	assert(pplist);
	pList p;
	if (*pplist == NULL)
		return;
	else
	{
		p = (*pplist)->next;
		free(*pplist);
		*pplist = p;
	}
}
//找出指定元素
pList Find(pList plist, DataType d)
{
	assert(plist);
	while (plist)
	{
		if (plist->data == d)
			return plist;
		else
			plist = plist->next;
	}
	return NULL;
}
//在指定位置之前插入一個值 
void Insert(pList* pplist, pList pos, DataType d)
{
	assert(pplist);
	pList tmp = *pplist;
	while (tmp->next->data != pos->data)
	{
		tmp = tmp->next;
	}
	pos = tmp->next;
	tmp->next = BuyNode(d);
	tmp->next->next = pos;
}
//指定位置刪除 
void Erase(pList* pplist, pList pos)
{
	assert(pplist);
	pList tmp = *pplist;
	if (tmp == NULL)
		return;
	if (tmp->next == NULL)
	{
		PopBack(pplist);
		return;
	}
	while (tmp->next != pos)
	{
		tmp = tmp->next;
	}
	pos = tmp->next->next;
	free(tmp->next);
	tmp->next = pos;
}
//刪除指定元素
void Remove(pList* pplist, DataType d)
{
	assert(pplist);
	pList tmp = *pplist;
	if (tmp == NULL)
		return;
	if (tmp->next == NULL)
	{
		PopBack(pplist);
		return;
	}
	while (tmp->next->data != d)
	{
		tmp = tmp->next;
	}
	pList cur = tmp->next->next;
	free(tmp->next);
	tmp->next = cur;
}
//刪除所有的指定元素
void RemoveAll(pList* pplist, DataType d)
{
	assert(pplist);
	pList tmp = *pplist;
	while (tmp->next)
	{
		if (tmp->data == d)
		{
			pList p = tmp->next;
			free(tmp);
			tmp = p;
		}
		else
		{
			if (tmp->next->data == d)
			{
				pList cur = tmp->next->next;
				free(tmp->next);
				tmp->next = cur;
			}
			else
				tmp = tmp->next;
		}
	}
}
//列印
void PrintLinkList(pList plist)
{
	assert(plist);
	while (plist)
	{
		printf("%d ", plist->data);
		plist=plist->next;
	}
	printf("\n");
}
//連結串列長
int GetListLength(pList plist)
{
	assert(plist);
	int count = 1;
	while (plist->next != NULL)
	{
		plist = plist->next;
		count++;
	}
	return count;
}
//逆序列印單項鍊表 
void PrintTailToHead(pList plist)
{
	assert(plist);
	pList tmp = NULL;
	while (plist->next != tmp)
	{
		pList cur = plist;
		while (cur->next->next != tmp)
		{
			cur = cur->next;
		}
		printf("%d ", cur->next->data);
		tmp = cur->next;
	}
	printf("%d\n", plist->data);
}

3、寫一個測試(test.c)讓程式碼跑起來並加以驗證