在 C 语言的链表中查找最小的两个节点
finding smallest two nodes in a linked list in c
我正在尝试在C++的链表中查找最小的两个数字(不使用任何内置函数)。
我尝试这样做如下:
我的逻辑是:
(1)假设链表中的第一个节点minimum1
,第二个节点minimum2
。比较它们。越大越minimum2
越小minimum1
.
(2)从第三个节点(第三个节点,因为我们已经涵盖了第一个和第二个节点)开始,直到我们到达NULL
,从而遍历所有列表。
(3)将新遍历的节点与minimum1
和minimum2
进行比较。如果此节点小于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->freq
与min1->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;
}
- 如何使用发送数据包所花费的时间计算两个节点之间的距离?
- 检查两个节点在子节点上是否具有相同状态的更优雅的方法
- 比较两个节点坐标的最佳方法是什么?
- 使用 Dijkstra 算法跟踪两个节点之间的最短路径
- 图问题:找出两个节点是否在每个节点的O(1)时间和O(2)存储中共享同一分支
- 如何在单个链表中交换两个节点的位置,只修改指针
- 如何遍历具有两个节点的链接节点
- 查找树中两个节点之间的最大成本边
- 查找树(不属于任何特定类型的简单连接树)中两个节点之间的路径
- 为什么不交换两个节点?
- 使用 Dijkstra 算法计算两个节点之间的最短路径
- 在 C 语言的链表中查找最小的两个节点
- 当两个节点相互指向时,不可避免的内存泄漏
- 如何使用BFS查找两个节点之间的距离
- 添加两个节点并在比较时删除一个节点
- 如何在C++中合并二叉树的两个节点
- 树中两个节点之间的最小距离
- 反转两个节点之间的链表
- 切换链表中的两个节点
- 查找树中两个节点的最小共同祖先