自实现链表的相关操作

自实现链表的相关操作

对于将Node* head作为参数传入函数中后,对head的赋值,最终不会改变head的指向,因为一级指针只能改变指向的值,只有二级指针才能改变一级指针的指向

#include "stdafx.h"
#include <stdlib.h>
#include <time.h>


typedef struct node
{
	int data;
	struct node *next;
}Node;


//创建一个空链表
Node* createList()
{
	Node* head = (Node*)malloc(sizeof(Node));
	head->next = NULL;
	return head;
}

//头插法插入节点
void headInsert(Node* head, int insertNumber)
{
	Node* cur = (Node*)malloc(sizeof(Node));
	cur->data = insertNumber;

	cur->next = head->next;
	head->next = cur;
}


//尾插法插入节点
void tailInsert(Node* head, int insertNumber)
{
	static Node* pt = head;//为了保证pt不断变化

	//main中的for循环会重复调用此函数,而不是一次插入所有节点
	//所以需要一个在函数结束后也存在的指针一直指向链表的尾节点

	Node* cur = (Node*)malloc(sizeof(Node));

	cur->data = insertNumber;

	pt->next = cur;
	cur->next = NULL;
	pt = pt->next;//pt=cur;
}


//遍历链表
void traverseList(Node* head)
{
	head = head->next;//越过头节点
	while (head != NULL)
	{
		printf("%d\n", head->data);
		head = head->next;
	}
}


//求链表的长度
int lenList(Node* head)
{
	int len = 0;
	head = head->next;
	while (head != NULL)
	{
		len++;
		head = head->next;
	}
	return len;
}


//查找节点(返回此节点的地址)
Node* searchList(Node* head,int findData)
{
	head = head->next;
	while (head != NULL)
	{
		if (findData == head->data)
		{
			return head;
		}
		head = head->next;
	}
	return NULL;
}


//删除节点(主要查找所要删除节点的前一个节点的地址)
void deleteList(Node* head, Node* pfind)
{
	while (head->next != pfind) head = head->next;//得到前趋节点

	head->next = pfind->next;//将所删节点俩边连接上

	free(pfind);//释放所删节点
}


//链表的冒泡排序(值的交换)
void sortPopList_Value(Node* head, int len)//长度len相当于冒泡排序中的个数
{
	Node* cur = head;//head的替身
	int tmp;

	for (int i = 0; i < len - 1; i++)//控制趟数
	{
		//每次大循环都是将cur指向头节点的下一个节点,并从cur开始往后进行比较(冒泡)
		cur = head->next;
		for (int j = 0; j < len - 1 - i; j++)//控制次数(不再推动比较)
		{
			if (cur->data > cur->next->data)//头指针的后俩个节点进行比较
			{
				tmp = cur->data;
				cur->data = cur->next->data;
				cur->next->data = tmp;
			}
			cur = cur->next;
			//作为推动比较的条件,cur往后进一步,cur->next固然也相当于往后走一步
		}
	}
}


//链表的冒泡排序(指针的交换)
void sortPopList_Point(Node* head, int len)
{
	Node* sh = NULL;//头指针的替身
	Node* p = NULL;//第一个比较节点
	Node* q = NULL;//第二个比较节点
	Node* tmp = NULL;//储存地址的容器

	for (int i = 0; i < len - 1; i++)
	{
		sh = head;
		p = sh->next;
		q = p->next;
		for (int j = 0; j < len - 1 - i; j++)
		{
			if (p->data > q->data)//前一个节点值大于后一个节点值
			{
				//交换俩个节点
				sh->next = q;
				p->next = q->next;
				q->next = p;
				//俩个节点交换后p、q位置发生改变,需要交换p、q地址的位置
				//因为需要符合 if中的判断条件 pq必须进行交换
				tmp = q;
				q = p;
				p = tmp;
			}
			//不管是否发生交换三个值都需要往后走推动循环
			sh = sh->next;
			p = p->next;
			q = q->next;
		}
	}
}


//链表的反转
void reverseList(Node* head)
{
	Node* p;
	Node* q;
	p = head->next;//p指向头节点的下一个节点
	head->next = NULL;//先打断链表,将链表一分为二
	while (p != NULL)//判断待插入的节点是否为空
	{
		q = p->next;//保存p的下一个节点
		//进行头插
		p->next = head->next;
		head->next = p;

		p = q;//将保存的节点重新赋值给p进行下一次判断,p的位置不能变动
	}
}


int _tmain(int argc, _TCHAR* argv[])
{
	srand(time(NULL));

	Node *head = createList();
	for (int i=0; i < 10; i++)
	{
		//tailInsert(head, i);
		//headInsert(head, rand()%100);
		headInsert(head, i);
	}
	//traverseList(head);

	//reverseList(head);
	//printf("after reverseList:\n");

	//traverseList(head);


	headInsert(head, 20);//确保有data为20的节点

	int len = lenList(head);
	printf("链表长=%d\n", len);

	traverseList(head);

	printf("========================================\n");

	Node* pfind = searchList(head, 20);


	if (NULL == pfind)
	{
		printf("find none\n");
	}
	else
	{
		printf("所查节点在链表中,地址为: %p\n",pfind);//已经查询到所要节点
		deleteList(head, pfind);
		traverseList(head);

		len = lenList(head);
		//sortPopList_Value(head, len);
		sortPopList_Point(head, len);
		printf("冒泡排序后:\n");
		traverseList(head);
	}

	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值