C语言中栈的高效实现

C语言中栈的高效实现,c,algorithm,performance,data-structures,stack,C,Algorithm,Performance,Data Structures,Stack,对于这个问题,我尝试用c实现堆栈数据结构。但我使用以下代码获得某些情况下的超时: #include <math.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <assert.h> #include <limits.h> #include <stdbool.h> struct Stack{ int top;


对于这个问题,我尝试用c实现堆栈数据结构。但我使用以下代码获得某些情况下的超时:

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
struct Stack{
    int top;
    int size;
    int sum;
    int* arr;
};
struct Stack* createStack(int size){
    struct Stack* stack = (struct Stack*)malloc(sizeof(struct Stack));
    stack->size=size;
    stack->top=-1;
    stack->sum=0;
    stack->arr = (int*)malloc(sizeof(int)*size);
    return stack;
}
int isempty(struct Stack* stack){
    if(stack->top==-1)
        return 1;
    return 0;
}
void push(struct Stack* stack,int term){
    stack->top++;
    stack->arr[stack->top]=term;
    stack->sum+=term;
}
void pop(struct Stack* stack){
    if(isempty(stack)==0){
        stack->sum-=stack->arr[stack->top];
        stack->top--;
    }
}
int main(){
    int size1,size2,size3;
    scanf("%d %d %d",&size1,&size2,&size3);
    int arr1[size1];
    for(int i=0;i<size1;i++)
        scanf("%d",&arr1[i]);
    struct Stack* stack1 = createStack(size1);
    for(int i=size1-1;i>=0;i--)
        push(stack1,arr1[i]);
    int arr2[size2];
    for(int i=0;i<size2;i++)
        scanf("%d",&arr2[i]);
    struct Stack* stack2 = createStack(size2);
    for(int i=size2-1;i>=0;i--)
        push(stack2,arr2[i]);
    int arr3[size3];
    for(int i=0;i<size3;i++)
        scanf("%d",&arr3[i]);
    struct Stack* stack3 = createStack(size3);
    for(int i=size3-1;i>=0;i--)
        push(stack3,arr3[i]);
    while(stack1->sum!=stack2->sum || stack2->sum!=stack3->sum){
        if(stack1->sum > stack2->sum && stack1->sum > stack3->sum)
            pop(stack1);
        if(stack2->sum > stack1->sum && stack2->sum > stack3->sum)
            pop(stack2);
        if(stack3->sum > stack2->sum && stack3->sum > stack1->sum)
            pop(stack3);
    }
    printf("%d\n",stack1->sum);
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
结构堆栈{
int top;
整数大小;
整数和;
int*arr;
};
结构堆栈*createStack(整数大小){
结构堆栈*堆栈=(结构堆栈*)malloc(sizeof(结构堆栈));
堆栈->大小=大小;
堆栈->顶部=-1;
堆栈->总和=0;
堆栈->arr=(int*)malloc(sizeof(int)*大小);
返回栈;
}
int isempty(结构堆栈*堆栈){
如果(堆栈->顶部==-1)
返回1;
返回0;
}
无效推送(结构堆栈*堆栈,整数项){
堆栈->top++;
堆栈->arr[堆栈->顶部]=术语;
堆栈->总和+=项;
}
void pop(结构堆栈*堆栈){
如果(isempty(堆栈)==0){
堆栈->总和-=堆栈->阵列[堆栈->顶部];
堆栈->顶部--;
}
}
int main(){
int size1、size2、size3;
scanf(“%d%d%d”、&size1、&size2、&size3);
国际arr1[size1];
对于(int i=0;i=0;i--)
推送(stack1,arr1[i]);
int arr2[size2];
对于(int i=0;i=0;i--)
推送(stack2,arr2[i]);
int arr3[size3];
对于(int i=0;i=0;i--)
推送(stack3,arr3[i]);
而(stack1->sum!=stack2->sum | stack2->sum!=stack3->sum){
如果(stack1->sum>stack2->sum&&stack1->sum>stack3->sum)
流行音乐(stack1);
如果(stack2->sum>stack1->sum&&stack2->sum>stack3->sum)
流行音乐(stack2);
if(stack3->sum>stack2->sum&&stack3->sum>stack1->sum)
流行音乐(stack3);
}
printf(“%d\n”,stack1->sum);
}

有谁能建议一种仅使用堆栈数据结构(最好是C)的更好方法吗?

您可以通过确定哪个堆栈具有最高的和,然后从该堆栈中弹出,直到其和等于或小于最低和来加快速度

查找具有最高和最低总和的堆栈的代码可能如下所示

struct Stack *high = (stack1->sum > stack2->sum) ? stack1 : stack2;
struct Stack *low  = (high == stack1) ? stack2 : stack1;

if ( stack3->sum > high->sum )
    high = stack3;
else if ( stack3->sum < low->sum )
    low = stack3;
while ( high->sum > low->sum )
    pop( high );

您可能会超过时间限制的原因是,如果

a) 任何堆栈都将变为空。您应该在while循环条件中添加该检查,即所有堆栈都不为空,然后输出所有三个堆栈的最小和


b) 可能存在高度为20、10、10的情况,在这种情况下,您的代码将如何工作?

为什么不使用链表而不是数组进行内部存储?您让hackerrank提供的代码作为起点,促使您使用堆栈来解决此问题(对于这样的练习来说,这可能是可以接受的目的)。考虑一下第二个栈的值。(对于一个更通用的堆栈,有<代码> POP()/代码>返回前一个代码。考虑代码> >(STACK1->和> STACK2->和&和STACK1->和StACK3->和)<代码> >(STACK2->和StACK1->和&和StACK2---SUM > STATK3-->和)< /C>'if(stack3->sum>stack2->sum&&stack3->sum>stack1->sum)`……这不是我做过的同一件事吗?……如果我错了,请纠正我。@yobro97您的代码中还有其他缺陷,正如公认的答案所指出的那样。特别地,考虑当总和为20、20和10时会发生什么。因为您的代码寻找一个堆栈高于其他两个堆栈,所以如果两个最大的堆栈相等,它不会做任何事情。但是这个答案会选择
stack2
作为
high
stack3
作为
low
,并且会从
stack2
中弹出。尽管如此,我并没有完全分析您的代码来发现这个问题。我只是对循环的编写方式有一种不好的感觉:分支点太多了。分支点(在代码中处理器需要做出决定的地方)会显著降低处理器的速度(通过导致管道暂停)。您的代码在循环中有8个分支点(不计算
pop
函数中的分支点)。我的代码是1。所以我的循环会跑得更快。事实证明,这不是问题所在,但我的解决方案还是解决了问题。谢谢你的建议……我不知道
分支点
…这肯定会对我有帮助……不过有一个问题……它对运行时间的影响有多大?@yobro97在本例中(将8个分支点替换为1个),我预计循环代码的运行速度会快2到3倍。但是,这在很大程度上取决于堆栈中的数据,因为这会影响实际执行的分支数。还有代码的其他部分所花费的时间。例如,如果使用
scanf
加载堆栈比运行循环花费的时间长,则会加快速度向上循环2到3次可能只会减少10到20%的总运行时间。这就是原因…关于(b)点,你是正确的…但是关于(a)点在pop函数中,我认为条件是空的。如果我将条件
=
而不是
包含在if条件中,法官会接受答案…..Thnx。。!!