单链表(增、删、查找)

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

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

}

时间: 2024-11-06 14:26:28

单链表(增、删、查找)的相关文章

java实现单链表增删改查

package 数据结构算法.链表; /* *定义节点 * 链表由节点构成 */ public class Node<E> { private E e; //数据data private Node<E> next; //指向下一个节点 public Node() { } public Node(E e) { this.e = e; } public Node<E> getNext() { return next; } public void setNext(Node&l

单链表的折半查找,冒泡排序,选择排序

//选择排序 void SelectSort(SeqList* pSeqList) { int i = 0, j = 0; int iMaxPos = 0; int iMinPos = 0; DataType temp; for (; i < pSeqList->Size/2; ++i) { iMaxPos = i; iMinPos = i; for(j = 1; j < pSeqList->Size - i; j++) { if (pSeqList->arry[iMaxPo

D_S 单链表的基本操作

//  main.cpp #include <iostream> using namespace std; #include "Status.h" #include "LinkList.h" int main() { LinkList L; int n,i; ElemType e; InitList(L); cout<<"\nL="; ListTraverse(L); cout<<"\n请设置将向线性

《实验课---单链表的基本操作》

//线性表---链表的基本操作#include<stdio.h>#include<stdlib.h>#include<conio.h>#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define NULL 0typedef int Status; //函数结果状态代码typedef int ElemType; //数据元素类型//------线性表的单链表存储结构

线性表之单链表学习小结(初学数据结构必看)

花了好几个小时,详细规划出了整个过程,包括所有基本操作...有什么疑问请下方留言 #include<iostream> using namespace std; #define ElemType char #define ERROR 0 #define OK 1 typedef struct Node { ElemType data; struct Node *next; }Node,*LinkList; void init_linklist(LinkList L)/*对单链表进行初始化*/

单链表的头插、尾插、删除、合并等操作

单链表的头插.尾插.删除.合并等操作实现代码如下: #include<iostream> using namespace std; //单链表的存储结构 typedef struct Node { int data; struct Node* next; }Node,*LinkList;//LinkList为结构指针类型 //初始化单链表 void InitList(LinkList *L) { *L = (LinkList)malloc(sizeof(Node));//建立头结点 (*L)-

详谈单链表的有关操作集锦~

1.单链表    在 Java 中没有显式的指针类型,然而实际上对象的访问就是使用指针来实现的,即在Java 中是使用对象的引用来替代指针的.因此在使用 Java 实现该结点结构时,一个结点本身就是一个对象.结点的数据域 data 可以使用一个 Object 类型的对象来实现,用于存储任何类型的数据元素,并通过对象的引用指向该元素:而指针域 next 可以通过节点对象的引 用来实现.      单链表结点结构是结点的一种最简单的形式,除此之外还有其他不同的结点结构,但是这些结点结构都有一个数据域

《数据结构》2.3单链表(single linked list)

1 #include <stdio.h> 2 int main(void) 3 { 4 //定义节点 5 typedef struct node 6 { 7 datatype data; 8 struct node *next; 9 }LNode,*LinkList; //LNode是节点类型,LinkList是指向LNode类型节点的指针类型 10 LinkList H; //定义头指针变量 11 12 //建立单链表(时间复杂度均为O(n)) 13 //逆序建立单链表(头插法) 14 Li

数据结构——单链表及其操作

1 #include<iostream> 2 #include<string> 3 #include<stdlib.h> 4 5 using namespace std; 6 7 typedef int ElemType; 8 typedef int Status; 9 #define OK 1 10 #define ERROR 0 11 12 13 //单链表的存储结构 14 typedef struct LNode 15 { 16 ElemType data; //

单链表的基本操作(一)

一.单链表的初始化: 1.生成新结点作为头结点,用头指针L指向头结点 2.头结点的指针域置空 Status InitList(LinkList &L) { //构造一个空的单链表L L=new LNode ;//生成新结点作为头结点,用头指针L指向头结点 L-next=NuLL;//头结点的指针域置空 return ok; } 二.取值: 1.用指针p指向首元结点,用j做计数器初值赋为1 2.从首元结点开始依次顺着链域next向下访问,只要指向当前结点的指针p不为空(NULL),并且没有到达序号