题目: 将链表中数据域值最小的结点移到链表的最前面(出自2017-3)
解答:
算法思想:循环遍历找到最小结点,记录最小结点的前结点的当前结点
核心代码
void MinToFirst(LinkList &L) {
LNode *pre = L; //最小结点p的前结点
LNode *p = L->next; //第一个结点
LNode *preMin = pre; //设最小前结点的前结点,即默认第一个元素为最小值
LNode *min = p; //默认第一个元素为最小值
while (p) {
if (min->data > p->data) {
preMin = pre; //p的前结点
min = p;
} else {
pre = p;
p = p->next;
}
}//while
preMin->next = min->next; //最小结点min的前结点连接上min结点的下一结点
min->next = L->next; //指向原先第一个元素
L->next = min; //头结点指向min最小结点
}
完整代码
#include "stdio.h"
#include "stdlib.h"
typedef struct LNode {
int data;
struct LNode *next;
} LNode, *LinkList;
//初始化一个单链表(带头结点)
bool InitList(LinkList &L) {
L = (LNode *) malloc(sizeof(LNode));
if (L == NULL)
return false;
L->next = NULL;
return true;
}
//判断 单链表是否为空(带头结点)
bool Empty(LinkList L) {
return L->next == NULL;
}
/**
* 后插操作: 在p结点之后插入元素e
* @param p
* @param e
* @return
*/
bool InsertNextNode(LNode *p, int e) {
if (p == NULL) return false;
LNode *s = (LNode *) malloc(sizeof(LNode));
if (s == NULL) return false;
s->data = e;
s->next = p->next;
p->next = s;
return true;
}
void PrintList(LinkList L) {
LNode *p = L->next;
while (p) {
printf("%d \t", p->data);
p = p->next;
}
}
void MinToFirst(LinkList &L) {
LNode *pre = L; //最小结点p的前结点
LNode *p = L->next; //第一个结点
LNode *preMin = pre; //设最小前结点的前结点,即默认第一个元素为最小值
LNode *min = p; //默认第一个元素为最小值
while (p) {
if (min->data > p->data) {
preMin = pre; //p的前结点
min = p;
} else {
pre = p;
p = p->next;
}
}//while
preMin->next = min->next; //最小结点min的前结点连接上min结点的下一结点
min->next = L->next; //指向原先第一个元素
L->next = min; //头结点指向min最小结点
}
int main() {
LinkList L;
InitList(L);
for (int i = 0; i < 5; i++) {
int e;
scanf("%d", &e);
InsertNextNode(L, e);
}
PrintList(L);
printf("\n");
//do
MinToFirst(L);
PrintList(L);
return 0;
}