在c中找到链表中最小的两个节点

时间:2014-03-12 21:56:59

标签: c++ c algorithm data-structures

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

我试着这样做:

我的逻辑是:

(1)假设链表中的第一个节点是minimum1,第二个节点是minimum2。比较他们。 {@ 1}}越大,minimum2越小。

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

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

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

代码

minumum1

我的代码不能处理以下输入(它输出错误):

#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);
}

它应该打印&#34; min1:-5&#34;和&#34; min2:-2&#34;但我不知道它为什么没有。

有人可以帮我解决这个问题吗?我们赞赏C / C ++中用作参考的任何算法或代码片段。谢谢。

注意:我无法使用任何内置功能。<​​/ p>

6 个答案:

答案 0 :(得分:2)

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

  
    
      
        

然后只做一件事,

      
    
  

以后,用另一种单一的努力来追随它。

即。

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

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


实施search1,对其进行调试,并使其正常工作。


之后

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

匹配

答案 1 :(得分:2)

你的行中有一个错误

if(var1>second)

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

行中还有另一个错误

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

和后一行

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

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

答案 2 :(得分:1)

我没有完整的答案,但我不相信在while循环中检查temp->next->next->next!=NULL。短名单会出现问题。

你最好一次看一件物品。将两个最小值设置为最大可能值(即INT_MAX),将节点指针设置为NULL。

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

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

答案 3 :(得分:1)

有两个整数min1,min2,两个INT_MAX(来自limits.h)。 (假设:没有元素可以具有值INT_MAX。)

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


如果它小于min1,那么min1现在是有史以来的第二个,所以将min1指定给min2。然后用元素替换min1 如果它不小于min1但小于min2,则它取代min2 如果不是上述内容,请跳过元素。


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

答案 4 :(得分:1)

这应该这样做:

#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 node\n");
    scanf("%d", &size);
    printf("start entering the number of elements until your size\n");
    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 list\n");
    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 : %d\n",min1->freq,min2->freq);
    } else
        printf("\n Not enough data\n\n");

}

//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;
}

答案 5 :(得分:1)

我使用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("check1\n");
    while (temp != NULL) 
    {
        printf("\ncheck2\n");       
        if ((temp) -> freq < min2 -> freq)
        {
            printf("check3\n");
            min1 = min2;
            min2 = temp;
        } 
        else if ((temp) -> freq < min1 -> freq && (temp) -> freq != min2 -> freq)
        {
            printf("check4\n");
            min1 = temp;
        }
        temp = temp -> next;
    }
    * lmin1 = min1; 
    * lmin2 = min2;
    printf("address of min2 is : %d  and value is %d \n" ,min2, min2->freq);    
    printf("check5\n"); 
}
//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 node\n");
    scanf("%d", & size);
    printf("start entering the number of elements until your size\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("\n The two minimum numbers are  min1 :%d   and min2 : %d\n", min1 -> freq, min2 -> freq);

}