单链表中节点类型定义如下:
typedef struct link {
int data;
link* next;
}node,*linklist;
1.试编写在带头节点的单链表L中删除一个最小值节点的高效算法(假设最小值节点时唯一的)
void delete_MinX(linklist& L) {
//试编写在带头节点的单链表L中删除一个最小值节点的高效算法(假设最小值节点时唯一的)
node* min_pre = L;//记录最小节点的前一个节点
node* min_p=L->next;//用于指向最小值节点
node* pre=L;//记录遍历时节点的前一个节点
node* p = L->next;
while (p != NULL){
if (p->data <min_p->data) {
min_pre = pre;
min_p = p;
}
pre = pre->next;
p = p->next;
}
min_pre->next = min_p->next;
cout << min_p->data<<endl;
}
2.设在一个带头节点的单链表中所有元素节点的数据值无序,试编写一个函数,删除表中所有介于给定的两个值(作为函数参数给出)之间的元素的元素
void delete_between(linklist& L, int x, int y) {
//设在一个带头节点的单链表中所有元素节点的数据值无序,试编写一个函数,
//删除表中所有介于给定的两个值(作为函数参数给出)之间的元素的元素
node* pre = L;
node* p = L->next;
while (p != NULL) {
if (p->data <= y && p->data >= x) {
pre->next = p->next;
p = p->next;
//free(p);
}
else {
pre = p;
p = p->next;
}
}
}
3.有一个带头节点的单链表L,设计一个算法使其元素递增有序
void sort(linklist& L) {
//有一个带头节点的单链表L,设计一个算法使其元素递增有序
//方法1:断链,逐个插入法;
if (L->next == NULL) {
return;
}
node* p = L->next;
node* rear = p->next;
p->next = NULL;//断链,让其只剩下一个节点,最后采用插入法;
p = rear;
while (p != NULL) {
rear = p->next;
node* q_pre = L;//指向被插入位置的前一个节点
node* q = L->next;
while (q != NULL&&q->data<p->data) {
q_pre = q;
q = q->next;
}
p->next = q_pre->next;
q_pre->next = p;
p = rear;
}
//方法2:交换元素值
/*int length = 0;
node* p = L->next;
while (p != NULL) {
length++;
p = p->next;
}
if (length <= 1) {
return;
}
node* pre = L->next;;
p = pre->next;
int t = 1;
while (t < length) {
int tt = 0;
pre = L->next;
p = pre->next;
while (tt < length - t) {
if (pre->data > p->data) {
int exchange = pre->data;
pre->data = p->data;
p->data = exchange;
}
pre = p;
p = p->next;
tt++;
}
t++;
}*/
}
4.给定两个单链表,编写算法找出两个链表的公共节点。
linklist Common(linklist A, linklist B) {
//给定两个单链表,编写算法找出两个链表的公共节点。
//算法思路:先走K步,然后一同走;
int length1 = 0;
int length2 = 0;
node* p = A->next;
node* q = B->next;
while (p != NULL) {
p = p->next;
length1++;
}
while (q != NULL) {
q = q->next;
length2++;
}
int k;
if (length1 >= length2) {
k = length1 - length2;
p = A->next;
while (k > 0) {
p = p->next;
k--;
}
q = B->next;
}
else {
k = length2 - length1;
q = B->next;
while (k > 0) {
q = q->next;
k--;
}
p = A->next;
}
while (p!=NULL&&q!=NULL&&p->data != q->data) {//同时走找公共节点
p = p->next;
q = q->next;
}
cout << p->data;
if (p->data == q->data) {
return p;
}
return NULL;
}
5.给定一个带表头节点的单链表,设head为头指针,试写出算法:按递增次序输出单链表中各结点的数据元素,并释放结点所占的存储空间
void fun1(linklist& head) {
//给定一个带表头节点的单链表,设head为头指针,试写出算法:
//按递增次序输出单链表中各结点的数据元素,并释放结点所占的存储空间
//不允许数组作为辅助空间
while (head->next != NULL) {
node* min_pre = head;
node* min_p = head->next;//设刚开始最小值就是第一个结点
node* pre = head;
node* p = head->next;
while (p != NULL) {
if (p->data < min_p->data) {
min_p = p;
min_pre = pre;
}
pre = p;
p = p->next;
}
cout << min_p->data << endl;
min_pre->next = min_p->next;
}
}
6.将一个带头节点的单链表分成两个单链表,A存放奇数结点,B存放偶数结点
void fun2(linklist& L) {
//将一个带头节点的单链表分成两个单链表,A存放奇数结点,B存放偶数结点
node* la = (node*)malloc(sizeof(node*));//创建链表A的头节点
node* lb = (node*)malloc(sizeof(node*));//创建链表B的头节点
la->next = NULL;
lb->next = NULL;
node* p = L->next;
node* rear = la;
int t = 1;
while (p != NULL) {
node* temp = p->next;
if (t % 2 == 1) {//采用尾插法
p->next = rear->next;
rear->next = p;
rear = p;
}
else {//采用头插法
p->next = lb->next;
lb->next = p;
}
t++;
p = temp;
}
display(la);
display(lb);
}
7.在一个递增有序的线性表中,有数值相同的元素存在,若存储方式为单链表,设计算法去掉数值相同的元素,使表中不再有重复的元素
void delete_same(linklist& L) {
//在一个递增有序的线性表中,有数值相同的元素存在,若存储方式为单链表,
//设计算法去掉数值相同的元素,使表中不再有重复的元素
node* pre = L->next;//指向大小相等的结点中的第一个结点
if (pre == NULL) {
return;
}
node* p = pre->next;
while (p != NULL) {
if (p->data == pre->data) {//说明中间有相同的元素
p = p->next;
}
else {
pre->next = p;
pre = p;
p = p->next;
}
}
}