单链表(增、删、查找)

     用结构体构建单链表,实现单链表的基本功能。



//头文件
#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;

}


本文出自 “二负” 博客,请务必保留此出处http://10324470.blog.51cto.com/10314470/1770126

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
单链表是一种常用的数据结构,它由一系列节点组成,每个节点包含一个数据元素和一个指向下一个节点的指针。单链表的操作包括加节点、除节点、修改节点和查找节点。下面是C语言实现单链表改查示例代码: ```c #include <stdio.h> #include <stdlib.h> // 节点结构体 typedef struct node { int data; // 数据元素 struct node* next; // 指向下一个节点的指针 } Node; // 在单链表末尾加节点 void addNode(Node** head, int data) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = data; newNode->next = NULL; if (*head == NULL) { *head = newNode; } else { Node* current = *head; while (current->next != NULL) { current = current->next; } current->next = newNode; } } // 在单链表指定位置插入节点 void insertNode(Node** head, int index, int data) { Node* newNode = (Node*)malloc(sizeof(Node)); newNode->data = data; if (index == 0) { newNode->next = *head; *head = newNode; } else { Node* current = *head; for (int i = 0; i < index - 1 && current != NULL; i++) { current = current->next; } if (current != NULL) { newNode->next = current->next; current->next = newNode; } else { printf("Index out of range\n"); } } } // 在单链表指定位置除节点 void deleteNode(Node** head, int index) { if (*head == NULL) { printf("List is empty\n"); return; } Node* current = *head; Node* previous = NULL; if (index == 0) { *head = current->next; free(current); } else { for (int i = 0; i < index && current != NULL; i++) { previous = current; current = current->next; } if (current != NULL) { previous->next = current->next; free(current); } else { printf("Index out of range\n"); } } } // 修改单链表指定位置节点的值 void modifyNode(Node* head, int index, int data) { if (head == NULL) { printf("List is empty\n"); return; } Node* current = head; for (int i = 0; i < index && current != NULL; i++) { current = current->next; } if (current != NULL) { current->data = data; } else { printf("Index out of range\n"); } } // 查找单链表指定位置节点的值 int searchNode(Node* head, int index) { if (head == NULL) { printf("List is empty\n"); return -1; } Node* current = head; for (int i = 0; i < index && current != NULL; i++) { current = current->next; } if (current != NULL) { return current->data; } else { printf("Index out of range\n"); return -1; } } // 打印单链表 void printList(Node* head) { if (head == NULL) { printf("List is empty\n"); return; } Node* current = head; printf("List: "); while (current != NULL) { printf("%d ", current->data); current = current->next; } printf("\n"); } int main() { Node* head = NULL; // 在单链表末尾加节点 addNode(&head, 1); addNode(&head, 2); addNode(&head, 3); printList(head); // 在单链表指定位置插入节点 insertNode(&head, 1, 4); insertNode(&head, 0, 5); insertNode(&head, 6, 6); printList(head); // 在单链表指定位置除节点 deleteNode(&head, 2); deleteNode(&head, 0); deleteNode(&head, 4); printList(head); // 修改单链表指定位置节点的值 modifyNode(head, 1, 7); modifyNode(head, 3, 8); modifyNode(head, 5, 9); printList(head); // 查找单链表指定位置节点的值 printf("Value at index 2: %d\n", searchNode(head, 2)); printf("Value at index 5: %d\n", searchNode(head, 5)); printf("Value at index 7: %d\n", searchNode(head, 7)); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值