1. 程式人生 > >單鏈表的增刪查詢操作

單鏈表的增刪查詢操作

#pragma once
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
typedef int DataType;

typedef struct SLitsNode
{
	DataType data;
	struct SLitsNode *next;
}SListNode;

//初始化、銷燬
void ListInit(SListNode **ppFirst)
{
	assert(ppFirst);
	*ppFirst = NULL;
}

void ListDestroy(SListNode **ppFirst)
{
	assert(ppFirst);
	SListNode *nextNode = NULL;
	SListNode *cur = *ppFirst;
	while (cur)
	{
		nextNode = cur->next;
		free(cur);
	}
	*ppFirst = NULL;
}

//建立新節點
SListNode *CreateNode(DataType data)
{
	SListNode *newNode = (SListNode *)malloc(sizeof(SListNode));
	assert(newNode);
	newNode->data = data;
	newNode->next = NULL;

	return newNode;
}

//增刪查改
//頭插
void  ListPushFront(SListNode **ppFirst, DataType data)
{
	assert(ppFirst);//考慮特殊情況,連結串列為空,但是這種情況依舊適合下列程式碼,所以沒關係
	SListNode *newNode = CreateNode(data);
	
	newNode->next = *ppFirst;
	*ppFirst = newNode;
}

//尾插(至少要有一個節點)
void  ListPushBack(SListNode **ppFirst, DataType data)
{
	assert(ppFirst);
	SListNode *newNode = CreateNode(data);
	if (*ppFirst == NULL)//如果連結串列為空
	{
		newNode->next = NULL;
		*ppFirst = newNode;
		return;
	}

	SListNode *cur = *ppFirst;
	while (cur->next != NULL)
	{
		cur = cur->next;
	}
	
	newNode->next = NULL;
	cur->next = newNode;
}

//查詢
SListNode *ListFind(SListNode *pFirst, DataType data)
{
	assert(pFirst);
	SListNode *cur = pFirst;
	for (cur = pFirst; cur != NULL; cur = cur->next)
	{
		if (data == cur->data)
		{
			return cur;
		}
	}
	return NULL;
}

//在節點pos前插入(節點在連結串列中)
void ListInsert(SListNode **ppFirst, SListNode *pos, DataType data)
{
	assert(ppFirst);
	if (pos == NULL){
		printf("have no pos\n");
		return;
	}
	if (pos == *ppFirst)
	{
		ListPushFront(ppFirst, data);
		return;
	}

	SListNode *cur = *ppFirst;
	while (cur->next != pos)
	{
		cur = cur->next;
	}

	SListNode *newNode = CreateNode(data);
	newNode->next = cur->next;
	cur->next = newNode;
}


//頭刪
void ListPopFront(SListNode **ppFirst)
{
	assert(ppFirst);
	assert(*ppFirst);//連結串列不能為空(特殊情況)
	SListNode *del = *ppFirst;
	*ppFirst = del->next;
	free(del);
}

//尾刪
void ListPopBack(SListNode **ppFirst)
{
	assert(ppFirst);
	assert(*ppFirst);//連結串列不能為空(特殊情況)
	if ((*ppFirst)->next == NULL)//特殊情況(連結串列只有一個節點)
	{
		free(*ppFirst);
		(*ppFirst) = NULL;
		return;
	}

	SListNode *del = NULL;
	SListNode *cur = *ppFirst;
	while (cur->next->next != NULL)
	{
		cur = cur->next;
	}

	del = cur->next;
	cur->next = NULL;
	free(del);
}

//刪除指定節點(節點在連結串列中)
void ListErase(SListNode **ppFirst, SListNode *pos)
{
	assert(ppFirst);
	assert(*ppFirst);
	if (pos == NULL){
		printf("have no pos\n");
		return;
	}

	if (pos == *ppFirst)
	{
		ListPopFront(ppFirst);
		return;
	}

	SListNode *cur = *ppFirst;
	SListNode *del = NULL;
	while (cur->next != pos)
	{
		cur = cur->next;
	}
	del = cur->next;
	cur->next = del->next;
	free(del);
}

void ListPrint(SListNode *pFirst)
{
	SListNode *cur = pFirst;
	while (cur)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

void Test()
{
	SListNode *first;//頭指標
	ListInit(&first);//first的指向要改變,所以要傳地址

	//ListPushBack(&first, 2);//尾插
	//ListPushFront(&first, 1);//頭插
	//ListPopFront(&first);
	//ListPopBack(&first);
	ListPushBack(&first, 1);//尾插
	ListPushBack(&first, 2);//尾插
	ListPushBack(&first, 3);//尾插
	ListPushBack(&first, 4);//尾插
	ListPushBack(&first, 5);//尾插
	//ListInsert(&first, ListFind(first, 2), 10);
	ListErase(&first, ListFind(first, 5));

	ListPrint(first);
}