在 C 语言的链表中查找最小的两个节点

finding smallest two nodes in a linked list in c

本文关键字:两个 节点 语言 链表 查找      更新时间:2023-10-16

我正在尝试在C++的链表中查找最小的两个数字(不使用任何内置函数)。

我尝试这样做如下:

我的逻辑是:

(1)假设链表中的第一个节点minimum1,第二个节点minimum2。比较它们。越大越minimum2越小minimum1.

(2)从第三个节点(第三个节点,因为我们已经涵盖了第一个和第二个节点)开始,直到我们到达NULL,从而遍历所有列表。

(3)将新遍历的节点与minimum1minimum2进行比较。如果此节点小于minimum1,则将其值放在minimum1中。minimum2现在将包含minimum1的值,minimum1将包含新找到的小于minumum1的节点的值。

下面是我的代码,它获取要创建的节点数,连续读取所有节点的值(只需在每个数字后继续按Enter键),然后从所有节点创建链表。这些工作正常。

法典

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
struct node
{
int freq;
struct node* next;
};
typedef struct node node;
node* tree;
// Finding minimum two elements:
void find_two_min(node** List, node** lmin1, node** lmin2)
{
int i;
node* temp = *List;
node *min1, *min2;
node* var1 = *List;
node* second = (*List)->next;
if (var1 > second)
{
min2 = var1;
min1 = second;
}
else
{
min1 = var1;
min2 = second;
}
while (temp->next->next->next != NULL)
{
if (temp->freq < min2->freq)
{
min1 = min2;
min2 = temp;
}
else if (temp->freq < min1->freq)
{
min1 = temp;
}
temp = temp->next;
}
*lmin1 = min1;
*lmin2 = min2;
}
void main()
{
int size, data;
node *min1, *min2;
int count = 0; // This flag is to check whether it's the first node inside the do-while loop.
tree = NULL;
printf("Enter the number of nodes:n");
scanf("%d", &size);
printf("Enter the elements:n");
node* prev;
do
{
scanf("%d", &data);
if (count == 0)
{
node* temp;
temp = (node*) malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
prev = temp;
tree = prev;
}
else
{
node* temp;
temp = (node*) malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
prev->next = temp;
prev = prev->next;
}
--size;
++count;
}
while (size > 0);
printf("Printing linked list:n");
node* temp1;
temp1 = tree;
while (temp1 != NULL)
{
printf("%d, ", temp1->freq);
temp1 = temp1->next;
}
node* temp5 = tree;
find_two_min(&temp5, &min1, &min2);
printf("nThe two minimum numbers are min1: %d and min2: %d.n", min1->freq, min2->freq);
}

我的代码不适用于以下输入(它给出了错误的输出):

Enter the number of nodes:
4
Enter the elements:
0
-5
-2
8
Printing linked list:
0, -5, -2, 8,
The two minimum numbers are min1: 0 and min2: -5.

它应该打印"min1:-5"和"min2:-2",但我不知道为什么不打印。

任何人都可以帮我解决这个问题吗?欢迎使用 C/C++ 中的任何算法或代码段作为参考。谢谢。

注意:我无法使用任何内置函数。

如果试图同时做两件事让你感到困惑,

然后只做一件事,

后来,再做一次奇异的努力。

1st - 编写 search1() 以查找最小的项目并记录节点指针。

第二 - 编写 search2() 以查找最小的项目,但在您的 search2 中添加将节点地址与之前找到的最小节点进行比较的想法。 当已经找到时,跳过它,就好像甚至不存在一样。


实现 search1,对其进行调试,然后使其正常工作。


然后

实现 search2(可能是副本)并传入在 search1 中找到的节点指针。 每次发现 search2 的最小节点的可能更新时, 插入测试以确定此节点是否与之前找到的节点匹配

你在行中有一个错误

if(var1>second)

这是比较两个节点的内存地址,而不是它们的频率!

行中还有另一个错误

if(temp->freq<min2->freq)

和后面的台词

else if(temp->freq<min1->freq)

第一行后面的if语句块中的代码的行为就像您temp->freqmin1->freq进行比较,而不是像您当前所做的那样min2->freq- 反之亦然,对于第二行之后的else if语句块中的代码。

有两个整数 min1, min2,都是INT_MAX(来自 limits.h)。(假设:任何元素都不能具有INT_MAX的值。

逐个浏览您的列表。对于每个元素,请执行以下操作:

如果它小于 min1,那么 min1

现在是有史以来第二小的,因此将 min1 分配给 min2。然后将 min1 替换为元素。
如果它不小于 min1 但小于 min2,则替换 min2。
如果以上都不是,请跳过元素。


迭代列表后,min1 将保存最小的列表值,min2 将保存第二小的列表值。如果 min2 INT_MAX,则列表只有一个元素。如果 min1 INT_MAX,则列表为空。

我没有完整的答案给你,但我不相信在一段时间循环中检查temp->next->next->next!=NULL。 短名单会有问题。

您最好一次查看一个项目。 将两个最小值设置为最大可能值(即INT_MAX) 和节点指针指向 NULL。

  • 如果列表中第一项的值小于两个最小值中的一个,请更新最小值和节点指针。
  • 如果列表中下一项的值小于两个最小值中的一个,请更新最小值和节点指针。 您可能需要重新排列最小值的顺序。
  • 重复此操作,直到查看完列表中的每个项目。

当你到达列表的末尾时,你应该有你的答案,指针操作将更容易跟踪/调试。

我已经使用INT_MAX解决了我的问题。它工作正常:

#include <stdio.h> 
#include <stdlib.h> 
#include <malloc.h>
#include <string.h> 
#include <limits.h>
struct node 
{
int freq;
struct node * next;
};
typedef struct node node;
node * tree;
//Problem creating area is below (code for finding minimum two elements)
void find_two_min(node * * List, node * * lmin1, node * * lmin2) 
{
node * temp = * List;
node * min1;
min1 = (node*) malloc(sizeof(node));
min1 -> freq = INT_MAX;
node * min2;
min2 = (node*) malloc(sizeof(node));
min2 -> freq = INT_MAX;  //This initialisation of INT_MAX to min2->freq creates problem because printf() statment above it works well but don't work below it.
printf("check1n");
while (temp != NULL) 
{
printf("ncheck2n");       
if ((temp) -> freq < min2 -> freq)
{
printf("check3n");
min1 = min2;
min2 = temp;
} 
else if ((temp) -> freq < min1 -> freq && (temp) -> freq != min2 -> freq)
{
printf("check4n");
min1 = temp;
}
temp = temp -> next;
}
* lmin1 = min1; 
* lmin2 = min2;
printf("address of min2 is : %d  and value is %d n" ,min2, min2->freq);    
printf("check5n"); 
}
//Problem creating area is above//
void main() 
{
int size, data;
node * min1;
node * min2;
int count = 0; //this count flag is to check is it's first node or not inside the do-while loop.
tree = NULL;
printf("enter the size of noden");
scanf("%d", & size);
printf("start entering the number of elements until your sizen");
node * prev;
do {
scanf("%d", & data);
if (count == 0)
{
node * temp;
temp = (node * ) malloc(sizeof(node));
temp -> freq = data;
temp -> next = NULL;
prev = temp;
tree = prev;
}
else 
{
node * temp;
temp = (node * ) malloc(sizeof(node));
temp -> freq = data;
temp -> next = NULL;
prev -> next = temp;
prev = prev -> next;
}
size--;
++count;
}
while (size > 0);
printf("Printing linked listn");
node * temp1;
temp1 = tree;
while (temp1 != NULL) 
{
printf("%d-> ", temp1 -> freq);
temp1 = temp1 -> next;
}
node * temp5 = tree;
find_two_min( & temp5, & min1, & min2);
printf("n The two minimum numbers are  min1 :%d   and min2 : %dn", min1 -> freq, min2 -> freq);
}

这应该可以做到:

#include <stdio.h> 
#include <stdlib.h> 
#include <malloc.h> 
#include <string.h>
struct node {
int freq;
struct node* next;
};
typedef struct node node;
//Function Prototype
void find_two_min(node**, node**, node**);
void main() {
node* min1 = (node*) malloc(sizeof(node));
node* min2 = (node*) malloc(sizeof(node));
node* tree = NULL;
node* prev;
node* temp1;
node* temp;
node* temp5 = tree;
int size, data;
int count = 0; //this count flag is to check is it's first node or not inside the do-while loop.
printf("enter the size of noden");
scanf("%d", &size);
printf("start entering the number of elements until your sizen");
do {
scanf("%d", & data);
if (count == 0) {
temp = (node*) malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
prev = temp;
tree = prev;
} else {
node* temp;
temp = (node*) malloc(sizeof(node));
temp->freq = data;
temp->next = NULL;
prev->next = temp;
prev = prev->next;
}
size--;
++count;
} while (size > 0);
printf("Printing linked listn");
temp1 = tree;
while (temp1) {
printf("%d-> ", temp1->freq);
temp1 = temp1->next;
}
if (count > 1) {
find_two_min(&tree, &min1, &min2);
printf("n The two minimumnumbers are  min1 :%d   and min2 : %dn",min1->freq,min2->freq);
} else
printf("n Not enough datann");
}
//Function Definition
void find_two_min(node** List,node** lmin1,node** lmin2) {
node* temp = *List;
node* min1;
node* min2;
node* var1 = *List;
node* second=(*List)->next;
/* OLD ONE    
if (var1->freq > second->freq) {
min2 = var1;
min1 = second;
} else {
min1 = var1;
min2 = second;
}
*/
if (var1->freq > second->freq) {
min1 = var1;
min2 = second;
} else {
min2 = var1;
min1 = second;
}
while(temp->next) {
printf("nCurrent freq is %d", temp->freq);
printf("nNext freq is %d", (temp->next)->freq);
if ((temp->next)->freq < min2->freq) {
printf("n  Condition one is fulfilled");
min1 = min2;
min2 = temp->next;    
} else if ((temp->next)->freq < min1->freq) {
printf("n  Condition two is fulfilled");
min1 = temp->next;
}
temp = temp->next;
}
*lmin1 = min1; 
*lmin2 = min2;
}