C语言数据结构——链表例题

在数据结构的体系中,链表是十分重要的一门必修课,关于链表的经典习题也有很多,这篇文章将针对链表的经典例题进行举例和讲解
首先对我们要使用的链表进行创建和插入数据

#include 
#include 
#include 

typedef struct Listnode
{
	int data;
	struct Listnode* next;
}ListNode;

void ListInit(ListNode* head)
{
	if (head == NULL)
	{
		printf("fail!");
		exit(-1);
	}
	head->data = 0;
	head->next = NULL;
}

void ListPushBack(ListNode* head,int x)
{
	ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
	if (newnode == NULL)
	{
		printf("fail!");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;
	ListNode* cur = head;
	if (head->next == NULL)
	{
		head->next = newnode;
	}
	else
	{
		while (cur->next)
		{
			cur = cur->next;
		}
		cur->next = newnode;
	}
}

void ListPrint(ListNode* head)
{
	ListNode* cur = head->next;
	while (cur)
	{
		printf("%d ", cur->data);
		cur = cur->next;
	}
}

int main()
{
	ListNode* head;
	head = (ListNode*)malloc(sizeof(ListNode));
	ListInit(head);
	ListPushBack(head,8);
	ListPushBack(head,3);
	ListPushBack(head,7);
	ListPushBack(head,6);
	ListPushBack(head,2);
	ListPushBack(head,9);
	ListPushBack(head,6);
	ListPushBack(head,1);
	ListPrint(head);
	return 0;
}

运行的结果如下:
在这里插入图片描述

这里主要设计的知识是链表的知识,详细的说明可以看博客其他有关于链表概念的文章

链表元素排序(从小到大)

这里我们采用比较简单的冒泡排序算法,首先我们先来回顾一下冒泡排序算法的主要内容

冒泡排序

#include 

void Sort(int a[], int sz)
{
	int i = 0;
	int j = 0;
	for (i = 0;i < sz;i++)
	{
		for (j = 0;j < sz - i - 1;j++)
		{
			if (a[j] > a[j + 1])
			{
				int tmp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = tmp;
			}
		}
	}
}

int main()
{
	int a[5] = { 5,6,9,8,3 };
	Sort(a,5);
	for (int i = 0;i < 5;i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}

链表内部接口函数

void ListSort(ListNode* head)
{
	int i, count = 0, num;//count记录链表结点的个数,num进行内层循环,
	ListNode* tmp, *next, *tail;//创建三个指针,进行冒泡排序
	tmp = head;
	while (tmp->next != NULL)//计算出结点的个数
	{
		count++;
		tmp = tmp->next;
	}
	for (i = 0; i < count - 1; i++)//外层循环,跟数组冒泡排序一样
	{
		num = count - i - 1;//记录内层循环需要的次数,跟数组冒泡排序一样
		tmp = head->next;
		next = tmp->next;
		tail = tmp;
		while (num)
		{
			num--;
			if (tmp->data > next->data)
			{
				tmp->next = next->next;
				next->next = tmp;
				tail->next = next;
			}
			tail = tail->next;
			tmp = tail->next;
			next = tmp->next;
		}
	}
}

反向输出链表

void ListReverse(ListNode* head)
{
	ListNode* cur = head;
	ListNode* tmp = head;
	ListNode* pre = NULL;
	while (cur)
	{
		tmp = cur->next;
		cur->next = pre;
		pre = cur;
		cur = tmp;
	}
	head = pre;
}

下面对这个上面的代码进行解释:
先定义一个cur指针存放头结点,再定义一个tmp临时指针用来暂时存放遍历过程中cur的下一个结点,pre指针代表着头结点的移动

在链表中间删除指定元素

这里分为两种指定元素的形式,第一种是告诉元素是第几个元素进行删除,第二种是告诉需要删除元素的具体值进行删除

第一种删除方式

void ListErase1(ListNode* head, int pos)
{
	int i = 0;
	ListNode* cur = head;
	ListNode* tmp = head;
	for (i = 0;i < pos;i++)
	{
		tmp = cur;//记录下寻找元素之前的结点
		cur = cur->next;
	}
	ListNode* next = cur->next;
	tmp->next = next;
}

第二种删除方式

void ListErase2(ListNode* head, int x)
{
	ListNode* tmp = head;
	ListNode* cur = head;
	while (cur->data != x)
	{
		tmp = cur;
		cur = cur->next;
	}
	tmp->next = cur->next;
}

在链表中间添加指定元素

void ListAdd(ListNode* head, int x, int pos)
{
	int i = 0;
	ListNode* cur = head;
	ListNode* tmp = head;
	for (i = 0;i < pos;i++)
	{
		tmp = cur;
		cur = cur->next;
	}
	ListNode* newnode = (ListNode*)malloc(sizeof(ListNode));
	newnode->data = x;
	newnode->next = cur->next;
	cur->next = newnode;
}

你可能感兴趣的:(链表,数据结构,c语言)