單鏈表(增、刪、查找)

     用結構體構建單鏈表,實現單鏈表的基本功能。



//頭文件
#pragma once
#include<stdio.h>
#include<assert.h>
#include<malloc.h>


typedef int DataType;
typedef struct ListNode
{
	DataType _data;
	struct ListNode *_next;
}ListNode;


//初始化
void InitList(ListNode **ppHead)
{
	*ppHead = NULL;
}

//銷燬節點
void DestoryList(ListNode*& pHead)
{
	ListNode* cur = pHead;
	while (cur)
	{
		ListNode* tmp = cur;
		cur = cur->_next;
		free(tmp);
	}
	pHead = NULL;
}

ListNode* BuyNode(DataType x)
{
	ListNode* tmp = (ListNode*)malloc(sizeof(ListNode));
	assert(tmp);

	tmp->_data = x;
	tmp->_next = NULL;
	return tmp;
}

//尾插  
void PushBack(ListNode** ppHead, DataType x)   
{
	assert(ppHead);

	if (*ppHead = NULL)
	{
		*ppHead = BuyNode(x);
	}
	else
	{
		ListNode *tail = *ppHead;
		while (tail->_next != NULL)
		{
			tail = tail->_next;
		}
		tail->_next = BuyNode(x);
	}
}

//頭插
void PushFront(ListNode* &pHead, DataType x)
{
	if (pHead == NULL)
	{
		pHead = BuyNode(x);
	}
	else
	{
		ListNode * tmp = BuyNode(x);
		tmp->_next = pHead;
		pHead = tmp;
	}
}

void PrintList(ListNode *pHead)
{
	ListNode *cur = pHead;
	while (cur != NULL)
	{
		printf("%d->", cur->_data);
		cur = cur->_next;
	}
	printf("NULL\n");
}

//尾刪
void PopBack(ListNode* &pHead)
{
	if (pHead == NULL)
	{
		printf("List is empty\n");
		return;
	}
	else if (pHead->_next == NULL)
	{
		free(pHead);
		pHead = NULL;
	}
	else
	{
		ListNode* prevTail = NULL, *tail = pHead;
		while (tail->_next != NULL)
		{
			prevTail = tail;
			tail = tail->_next;
		}
		prevTail->_next = NULL;
		free(tail);
	}
}

//頭刪
void PopFront(ListNode*& pHead)
{
	if (pHead == NULL)
	{
		printf("List is empty.\n");
		return;
	}
	else
	{
		ListNode* tmp = pHead;
		pHead = tmp->_next;
		free(tmp);	
	}
}

ListNode *Find(ListNode *pHead, DataType x)
{
	ListNode *cur = pHead;
	while (cur)
	{
		if (cur->_data == x)
		{
			return cur;
		}
		cur = cur->_next;
	}
	return NULL;
}

void Insert(ListNode* pos, DataType x)
{
	assert(pos);

	ListNode *tmp = BuyNode(x);
	tmp->_next = pos->_next;
	pos->_next = tmp;

	/*ListNode *next = pos->_next;
	ListNode *tmp = BuyNode(x);  //插入的節點
	pos->_next = tmp;
	tmp->_next = next;
	*/
}

void Erase(ListNode* &pHead, ListNode *pos)
{
	assert(pos);

	
	if (pos == pHead)
	{
		pHead = pHead->_next;
		free(pHead);
	}
	else
	{
		ListNode* cur = pHead;
		while (cur)
		{
			if (cur->_next != pos)
			{
				cur->_next = pos->_next;
				free(pos);
				break;
			}
			cur = cur->_next;
		}
	}
}

void DelNonTailNode(ListNode* pos)//刪除不知頭和不是尾部的節點
{
	assert(pos&&pos->_next);

	pos->_data = pos->_next->_data;
	ListNode *next = pos->_next->_next;
	free(pos);
	pos->_next = next;
}

void Remove(ListNode* &pHead, DataType x)
{
	ListNode* ret = Find(pHead, x);
	if (ret)
	{
		Erase(pHead, ret);
	}
/*
	ListNode *node1 = pHead;
	ListNode *node2 = NULL;
	if (pHead == NULL)
	{
		return ;
	}
	else
	{
		if (node1->_data == x)
		{
			pHead = pHead->_next;
			free(node1);
			return ;
		}
		else
		{
			while (node1 != NULL)
			{
				node2 = node1;
				node2 = node2->_next;
				if (node2->_data== x)
				{
					node1->_next = node2->_next;
					free(node2);
					break;
				}
				node1 = node1->_next;
			}
		}
	}*/
}

void Reverse(ListNode* &pHead)      //逆置
{
	if (pHead == NULL || pHead->_next == NULL)
	{
		return;
	}
	ListNode* cur = pHead;
	ListNode* newHead = NULL;
	while (cur)
	{
		ListNode* tmp = cur;
		cur = cur->_next;
		tmp->_next = newHead;
		newHead = tmp;
	}
	pHead = newHead;
}

void PrintTailToHead(ListNode *pHead)
{
	if (pHead)
	{
		PrintTailToHead(pHead->_next);

		printf("%d\n",pHead->_data);
	}
}

ListNode* FindMid(ListNode* pHead)//查找單鏈表的中間節點,要求只能遍歷一次鏈表(快慢指針,一個走一步,另一個走兩步)
{
	if (pHead == NULL || pHead->_next == NULL)
	{
		return pHead;
	}

	ListNode* fast = pHead;
	ListNode* slow = pHead;
	while (fast)
	{
		fast = fast->_next->_next;
		slow = slow->_next;
	}
	return slow;
}

void InsertFrontNode(ListNode* pos,DataType x)
{
	assert(pos);

	ListNode* tmp = BuyNode(x);
	tmp->_next = pos->_next;
	pos->_next = tmp;

	DataType tmpData = tmp->_data;
	tmp->_data = pos->_data;
	pos->_data = tmpData;

}

ListNode* JosephCycle(ListNode* pHead, int m)//刪除節點
{
	ListNode* cur = pHead;
	if (cur == NULL)
		return NULL;

	while (1)
	{
		//只剩一個節點
		if (cur = cur->_next)
		{
			return cur;
		}

		int x = m;
		while (--x)//走m-1步
		{
			cur = cur->_next;
		}
		//替換法進行刪除
		cur->_data = cur->_next->_data;
		ListNode* del = cur->_next;
		cur->_next = del->_next;

		free(del);
	}
}


//快速排序
//冒泡排序
void SortList(ListNode* pHead)
{

	if (pHead == NULL || pHead->_next == NULL)
		return;
	ListNode *tail = NULL;
	ListNode*cur = pHead->_next;
	ListNode*prev = pHead;

	while (tail != pHead)
	{
		int exchange = 0;//優化不交換情況
		while (cur != tail)
		{

			if (cur->_data <prev->_data)
			{
				DataType temp = cur->_data;
				cur->_data = prev->_data;
				prev->_data = temp;
				exchange = 1;
			}
			prev = cur;
			cur = cur->_next;
		}
		if (exchange == 0)
			return;
		tail = prev;

		prev = pHead;
		cur = pHead->_next;
	}
}


//合併兩個有序鏈表,合併後仍有序   先摘  後尾插
ListNode* MergeList(ListNode *pHead1, ListNode* pHead2)
{
	if (pHead1 == NULL)
	{
		return pHead2;
	}
	if (pHead2 == NULL)
	{
		return pHead1;
	}

	ListNode*cur1 = pHead1;
}

ListNode* FindKTailNode(ListNode* pHead, int k)
{
	ListNode *fast = pHead, *slow = pHead;
	while (--k)
	{
		if (fast == NULL)
		{
			return NULL;
		}
		fast = fast->_next;

		if (fast == NULL)
		{
			return NULL;
		}
	}

	while (fast->_next)
	{
		slow = slow->_next;
		fast = fast->_next;
	}
	return slow;
}

//合併兩個有序鏈表
ListNode* MergeList(ListNode*pHead1, ListNode*pHead2)
{
	if (pHead1 == NULL)
		return pHead2;
	if (pHead2 == NULL)
		return pHead1;
	ListNode*newHead;
	ListNode*cur1 = pHead1;
	ListNode*cur2 = pHead2;
	ListNode*tail = NULL;
	if (cur1->_data < cur2->_data)
	{
		newHead = cur1;
		cur1 = cur1->_next;
	}
	else
	{
		newHead = cur2;
		cur2 = cur2->_next;
	}
	tail = newHead;//
	while (cur1&&cur2)
	{
		if (cur1->_data< cur2->_data)
		{
			tail->_next = cur1;
			cur1 = cur1->_next;
		}
		else
		{
			tail->_next = cur2;
			cur2 = cur2->_next;
		}
		tail = tail->_next;

		if (cur1 == NULL)
			tail->_next = cur2;
		if (cur2 == NULL)
			tail->_next = cur1;
	}
	return newHead;
}


//判斷鏈表是否帶環,環長度,環入口點
void RingList(ListNode* pHead)
{

	ListNode*slow = pHead;
	ListNode*fast = pHead;


	while (fast->_next)
	{

		slow = slow->_next;
		fast = fast->_next;
		if (fast->_next)
			fast = fast->_next;
		if (slow == fast)
		{
			printf( "鏈表中存在環\n" );
			//ListNode *tmp = slow;
			slow = slow->_next;
			int k = 1;
			while (slow != fast)
			{
				slow = slow->_next;
				k++;
			}
			printf("鏈表環長度爲 %d\n", k );
			//一步走必然會在環上次相遇的地方再次相遇
			//當slow進入環時,必然會與fast相遇,最初想遇的就是環入口點
			slow = pHead;
			while (slow != fast)
			{
				slow = slow->_next;
				fast = fast->_next;
			}

			printf( "環入口值爲:%d\n" , slow->_data );
			return;
		}

	}
	printf("鏈表中不帶環\n");
}

//鏈表相交
void Intersect(ListNode*pHead1, ListNode * pHead2)
{
	if (pHead1 == NULL || pHead2 == NULL)
	{
		printf( "List is not insersect\n" );
		return;
	}

	ListNode *cur1 = pHead1;
	ListNode *cur2;
	while (cur1)
	{
		cur2 = pHead2;
		cur1 = cur1->_next;
		while (cur2)
		{
			if (cur1 == cur2)
			{
				printf( "鏈表相交,交點值爲:%d\n", cur1->_data );
				return;
			}
			cur2 = cur2->_next;
		}

	}
	printf( "鏈表不相交\n");
	return;
}


int Size(ListNode*pHead)
{
	assert(pHead);

	int size = 0;
	ListNode*cur = pHead->_next;

	while (cur)
	{
		++size;
		cur = cur->_next;
	}
	return size;
}



//測試



#include<stdio.h>

#include"ListNode.h"


void test1()

{

ListNode * list = NULL;

PushBack(&list, 1);

PushBack(&list, 2);

PrintList(list);


PopFront(list);

PopFront(list);

PopFront(list);

PrintList(list);



ListNode* ret = Find(list, 3);

Erase(list, ret);

PrintList(list);


ListNode *ret1 = Find(list, 3);

InsertFrontNode(list, ret1->_data);

}


int main()

{

test1();

return 0;

}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章