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