【数据结构】栈和队列相关面试题_码农印象的博客-程序员信息网

技术标签: 数据结构知识总结    队列  面试题  

栈和队列面试题(c语言实现)

  • 1.实现一个栈,要求实现Push(入栈)、Pop(出栈)、Min(返回最小值)的时间复杂度为O(1).
  • 2.使用两个栈实现一个队列
  • 3.使用两个队列实现一个栈
  • 4.元素出栈、入栈的合法性。如入栈的序列(1,2,3,4,5),出栈序列为(4,5,3,2,1)
  • 5.一个数组实现两个共享栈
1.实现一个栈,要求实现Push(入栈)、Pop(出栈)、Min(返回最小值)的时间复杂度为O(1).

思路:
这里写图片描述
参考代码:

//构建两个栈,一个栈存储元素,另一个栈存储当前最小值

typedef struct MinStack
{
    Stack s;
    Stack mins;
}MinStack;

void MinStackInit(MinStack* pms);
void MinStackDestory(MinStack* pms);

void MinStackPush(MinStack* pms, DataType x);
void MinStackPop(MinStack* pms);
int MinStackSize(MinStack* pms);
int MinStackEmpty(MinStack* pms);
DataType MinStackTop(MinStack* pms);
int MinStackMin(MinStack* pms);
void testmin();


void MinStackInit(MinStack* pms)
{
    assert(pms);
    StackInit(&pms->s);
    StackInit(&pms->mins);
}
void MinStackDestory(MinStack* pms)
{
    assert(pms);
    StackDestory(&pms->s);
    StackDestory(&pms->mins);

}

void MinStackPush(MinStack* pms, DataType x)
{
    assert(pms);
    StackPush(&pms->s, x);
    if (StackEmpty(&pms->mins) || StackTop(&pms->mins) >= x)
    {
        StackPush(&pms->mins, x);
    }

}
void MinStackPop(MinStack* pms)
{
    assert(pms);
    if (StackTop(&pms->mins) == StackTop(&pms->s))
    {
        StackPop(&pms->mins);
    }
    StackPop(&pms->s);

}
int MinStackSize(MinStack* pms)
{
    assert(pms);
    return StackSize(&pms->s);

}
int MinStackEmpty(MinStack* pms)
{
    assert(pms);
    return StackEmpty(&pms->s);
}
DataType MinStackTop(MinStack* pms)
{   
    assert(pms);
    return StackTop(&pms->s);


}
int MinStackMin(MinStack* pms)
{
    assert(pms);
    return StackTop(&pms->mins);

}

void testmin()
{
    MinStack s;
    MinStackInit(&s);

    MinStackPush(&s, 1);
    MinStackPush(&s, 2);
    MinStackPush(&s, 0);
    MinStackPush(&s, 0);
    MinStackPush(&s, 0);
    MinStackPush(&s, 8);
    MinStackPush(&s, 0);

    printf("大小:%d\n",MinStackSize(&s));
    printf("栈顶元素:%d\n",MinStackTop(&s));
    printf("最小值:%d\n",MinStackMin(&s));
    MinStackPop(&s);

    printf("大小:%d\n", MinStackSize(&s));
    printf("栈顶元素:%d\n", MinStackTop(&s));
    MinStackPop(&s);

    printf("大小:%d\n", MinStackSize(&s));
    printf("栈顶元素:%d\n", MinStackTop(&s));
    MinStackPop(&s);

    printf("大小:%d\n", MinStackSize(&s));
    printf("栈顶元素:%d\n", MinStackTop(&s));

    MinStackDestory(&s);

}
2.使用两个栈实现一个队列

思路:
这里写图片描述
参考代码:

typedef struct  QueueByTwoStack
{
    Stack s1;
    Stack s2;
}QueueByTwoStack;

void QueueByTwoStackInit(QueueByTwoStack* qts);
void QueueByTwoStackDestory(QueueByTwoStack* qts);

void QueueByTwoStackPush(QueueByTwoStack* qts, DataType x);
void QueueByTwoStackPop(QueueByTwoStack* qts);
DataType QueueByTwoStackFront(QueueByTwoStack* qts);
int QueueByTwoStackEmpty(QueueByTwoStack* qts);
int QueueByTwoStackSize(QueueByTwoStack* qts);
void testQueueByTwoStack();

void QueueByTwoStackInit(QueueByTwoStack* qts)
{
    assert(qts);
    StackInit(&qts->s1);
    StackInit(&qts->s2);
}
void QueueByTwoStackDestory(QueueByTwoStack* qts)
{
    assert(qts);
    StackDestory(&qts->s1);
    StackDestory(&qts->s2);

}

// 栈s1入数据,s2出数据,
void QueueByTwoStackPush(QueueByTwoStack* qts, DataType x)
{
    assert(qts);
    StackPush(&qts->s1, x);

}
//s2出数据,如果有数据直接出,如果没有就从s1中把数据倒过来
void QueueByTwoStackPop(QueueByTwoStack* qts)
{
    assert(qts);
    if (StackEmpty(&qts->s2))
    {
        while (!StackEmpty(&qts->s1))
        {
            StackPush(&qts->s2, StackTop(&qts->s1));
            StackPop(&qts->s1);
        }
    }
    StackPop(&qts->s2);

}
DataType QueueByTwoStackFront(QueueByTwoStack* qts)
{
    assert(qts);
    if (StackEmpty(&qts->s2))
    {
        while (!StackEmpty(&qts->s1))
        {
            StackPush(&qts->s2, StackTop(&qts->s1));
            StackPop(&qts->s1);
        }
    }
    return StackTop(&qts->s2);
}
int QueueByTwoStackEmpty(QueueByTwoStack* qts)
{
    assert(qts);
    return StackEmpty(&qts->s1)&StackEmpty(&qts->s2);
}
int QueueByTwoStackSize(QueueByTwoStack* qts)
{
    assert(qts);
    return StackSize(&qts->s1) + StackSize(&qts->s2);
}

void testQueueByTwoStack()
{
    QueueByTwoStack stq;
    QueueByTwoStackInit(&stq);
    QueueByTwoStackPush(&stq, 1);
    QueueByTwoStackPush(&stq, 2);
    QueueByTwoStackPush(&stq, 3);
    QueueByTwoStackPush(&stq, 4);
    QueueByTwoStackPop(&stq);

    QueueByTwoStackPush(&stq, 5);
    QueueByTwoStackPush(&stq, 6);
    QueueByTwoStackPush(&stq, 7);
    QueueByTwoStackPush(&stq, 8);

    printf("%d", QueueByTwoStackSize(&stq));

    while (!QueueByTwoStackEmpty(&stq))
    {
        printf("%d ", QueueByTwoStackFront(&stq));
        QueueByTwoStackPop(&stq);
    }
    QueueByTwoStackDestory(&stq);
}
3.使用两个队列实现一个栈

思路:
这里写图片描述
参考代码:

typedef struct  StackByTwoQueue
{
    Queue q1;
    Queue q2;
}StackByTwoQueue;

void StackByTwoQueueInit(StackByTwoQueue* stq);
void StackByTwoQueueDestory(StackByTwoQueue* stq);
void StackByTwoQueuePush(StackByTwoQueue* stq, DataType x);
void StackByTwoQueuePop(StackByTwoQueue* stq);
DataType StackByTwoQueueFront(StackByTwoQueue* stq);
int StackByTwoQueueEmpty(StackByTwoQueue* stq);
int StackByTwoQueueSize(StackByTwoQueue* stq);

void testStackByTwoQueue();


void StackByTwoQueueInit(StackByTwoQueue* stq)
{
    assert(stq);
    QueueInit(&stq->q1);
    QueueInit(&stq->q2);
}
void StackByTwoQueueDestory(StackByTwoQueue* stq)
{
    assert(stq);
    QueueDestory(&stq->q1);
    QueueDestory(&stq->q2);

}
//两个队列实现栈,开始入队时,q1空入q2,q2空入q1,非空队上插入数据,另一个队当出栈时的缓存区
void StackByTwoQueuePush(StackByTwoQueue* stq, DataType x)
{
    assert(stq);
    if (QueueEmpty(&stq->q1))
    {
        QueuePush(&stq->q2, x);
    }
    else
    {
        QueuePush(&stq->q1, x);
    }

}
//出栈时,将非空队列前n-1数据导入空队,将原非空队列第n个数据出队
void StackByTwoQueuePop(StackByTwoQueue* stq)
{
    assert(stq);
    Queue *empty = &stq->q1, *noempty = &stq->q2;
    if (!QueueEmpty(&stq->q1))
    {
        empty = &stq->q2;
        noempty = &stq->q1;
    }
    while (QueueSize(noempty) > 1)
    {
        QueuePush(empty, QueueFront(noempty));
        QueuePop(noempty);
    }
    QueuePop(noempty);

}
DataType StackByTwoQueueFront(StackByTwoQueue* stq)
{
    assert(stq);
    if (QueueEmpty(&stq->q1))
    {
        return QueueBack(&stq->q2);
    }
    else
        return QueueBack(&stq->q1);
}
int StackByTwoQueueEmpty(StackByTwoQueue* stq)
{
    assert(stq);
    return QueueEmpty(&stq->q1)&QueueEmpty(&stq->q2);
}
int StackByTwoQueueSize(StackByTwoQueue* stq)
{
    assert(stq);
    return QueueSize(&stq->q1) + QueueSize(&stq->q2);
}

void testStackByTwoQueue()
{
    StackByTwoQueue stq;
    StackByTwoQueueInit(&stq);
    StackByTwoQueuePush(&stq, 1);
    StackByTwoQueuePush(&stq, 2);
    StackByTwoQueuePush(&stq, 3);
    StackByTwoQueuePush(&stq, 4);
    StackByTwoQueuePop(&stq);

    StackByTwoQueuePush(&stq, 5);
    StackByTwoQueuePush(&stq, 6);
    StackByTwoQueuePush(&stq, 7);
    StackByTwoQueuePush(&stq, 8);

    printf("%d     ", StackByTwoQueueSize(&stq));

    while (!StackByTwoQueueEmpty(&stq))
    {
        printf("%d ", StackByTwoQueueFront(&stq));
        StackByTwoQueuePop(&stq);
    }
    StackByTwoQueueDestory(&stq);
}
4.元素出栈、入栈的合法性。如入栈的序列(1,2,3,4,5),出栈序列为(4,5,3,2,1)

思路:
如入栈的序列(1,2,3,4,5),出栈序列为(4,5,3,2,1)
传入两个数组,一个是进入栈的序列另一个是出栈顺序,创建一个栈,将进入栈的序列依次压入栈中,当进入序列和出栈序列的第一个元素相同时,弹出这个元素,同时出栈序列,向后走,该元素已经成功出栈,此时若入栈序列还有元素继续重复上述操作,直到,最后一个元素也入栈,这时栈中剩下的元素位置已经固定,只能从栈顶依次弹出,每次弹出前栈顶元素和弹出序列元素比较若相等则继续弹出,同时弹出序列向后移动,一旦栈顶元素和弹出序列不相等,说明弹出序列要弹出的元素不在栈顶,所以无法弹出,所以就是非法弹出,否则继续重复上述操作,直到栈中的元素数目为0,即栈空,证明弹出序列合法
这里写图片描述
参考代码:

int Check(int *stack_in, int *stack_out, int len_in, int len_out);
void testInWithOut();



int Check(int *in, int *out, int len_in, int len_out)
{
    /*Stack s;
    StackInit(&s);
    assert(stack_in && stack_out);
    //两个序列长度不相等,不合法  
    if (len_in != len_out)
        return 0;

    int j = 0;
    int i = 0;
    for (; i < len_in; i++)
    {
        StackPush(&s, stack_in[i]);
        //入栈序列栈顶元素与当前出栈序列元素不相等,不合法  
        while (StackSize(&s) > 0 && StackTop(&s) == stack_out[j])
        {
            StackPop(&s);
            j++;
        }
    }*/

    Stack s;
    StackInit(&s);
    assert(in && out);
    //两个序列长度不相等,不合法  
    if (len_in != len_out)
        return 0;

    int index = 0;
    int outdex = 0;

    while (index < len_in)
    {
        StackPush(&s, in[index]);
        index++;
        while (!StackEmpty(&s) && (StackTop(&s) == out[outdex]))
        {
            StackPop(&s);
            outdex++;
        }

    }

    //当所有出栈序列元素都匹配完之后,栈不为空,不合法
    if (StackEmpty(&s))
    {
        StackDestory(&s);
        return 1;
    }
    else
    {
        StackDestory(&s);
        return 0;
    }
}


void testInWithOut()
{
    int stack_in[] = { 1, 2, 3, 4, 5 };       //入栈序列  
    int stack_out[] = { 4, 5, 3, 2, 1 };      //出栈序列  
    int len_in = sizeof(stack_in) / sizeof(stack_in[0]);      //入栈序列长度  
    int len_out = sizeof(stack_out) / sizeof(stack_out[0]);   //出栈序列长度  
    int ret = Check(stack_in, stack_out, len_in, len_out);
    if (ret == 1)
        printf("合法\n");
    else
        printf("不合法\n");

}
5.一个数组实现两个共享栈

思路:
这里写图片描述
参考代码:

//方案一:

#define MAXSIZE 10
//利用数组实现一个静态共享栈,第一个栈是从前往后入栈,第二栈的元素从后往前放
typedef struct SharedStack
{
    int data[MAXSIZE];
    int top1;     //左栈顶
    int top2;     //右栈顶
}SharedStack;

//flag为判断区分两个栈 ,规定1为左栈,2为右栈

void SharedStackInit(SharedStack* s);

// 入栈 
void SharedStackPush(SharedStack* s, int data, int flag);
// 出栈 
void SharedStackPop(SharedStack* s, int flag);
// 获取栈顶元素 
int SharedStackTop(SharedStack* s, int flag);
// 有效元素的个数 
int SharedStackSize(SharedStack* s, int flag);
// 检测栈是否为空 
int SharedStackEmpty(SharedStack* s, int flag);

void SharedStackInit(SharedStack* s)
{
    s->top1 = 0;
    s->top2 = MAXSIZE - 1;
}

// 入栈 
void SharedStackPush(SharedStack* s, int data, int flag)
{
    if (s->top2 <= s->top1)
        return;

    if (1 == flag)
        s->data[s->top1++] = data;
    else
        s->data[s->top2--] = data;
}

// 出栈 
void SharedStackPop(SharedStack* s, int flag)
{
    if (SharedStackEmpty(s, flag))
        return;

    if (1 == flag)
        s->top1--;
    else
        s->top2++;
}

// 获取栈顶元素 
int SharedStackTop(SharedStack* s, int flag)
{
    assert(!SharedStackEmpty(s, flag));
    if (1 == flag)
        return s->data[s->top1 - 1];
    else
        return s->data[s->top2 + 1];
}

// 有效元素的个数 
int SharedStackSize(SharedStack* s, int flag)
{
    if (1 == flag)
        return s->top1;
    else
        return MAXSIZE - s->top2 - 1;
}

// 检测栈是否为空 
int SharedStackEmpty(SharedStack* s, int flag)
{
    if (1 == flag)
        return 0 == s->top1;
    else
        return MAXSIZE - 1 == s->top2;
}

//方案二;
typedef int SDataType;
typedef struct SShareStack
{
    SDataType* data;
    int top1;
    int top2;
    int capacity;

}SShareStack;

void  SShareStackInit(SShareStack* pss);
void  SShareStackDestory(SShareStack* pss,int flag);

void  SShareStackPush(SShareStack* pss,SDataType x,int flag);
void  SShareStackPop(SShareStack* pss, int flag);
int  SShareStackSize(SShareStack* pss, int flag);
SDataType  SShareStackTop(SShareStack* pss, int flag);
int  SShareStackEmpty(SShareStack* pss, int flag);
void testShareStack();

void  SShareStackInit(SShareStack* pss)
{
    assert(pss);
    pss->data = (SDataType*)malloc(sizeof(SDataType)* 4);
    pss->capacity = 4;
    pss->top1 = 0;
    pss->top2 = 1;
}
void  SShareStackDestory(SShareStack* pss,int flag)
{
    assert(pss);
    if (flag == 1)
    {
        pss->top1 = 0;
        if (pss->top2 == 1)
        {
            free(pss->data);
            pss->data = NULL;
        }

    }
    else
    {
        pss->top2 = 1;
        if (pss->top1 == 0)
        {
            free(pss->data);
            pss->data = NULL;
        }
    }                                                      

}

SDataType* AddCapacity(SShareStack* pss)
{
    assert(pss);
    SDataType* tmp = (SDataType*)realloc(pss->data, sizeof(SDataType)*(pss->capacity + 4));
    assert(tmp);
    pss->data = tmp;
    pss->capacity += 4;
    printf("增容成功\n");

    return pss->data;

}
void  SShareStackPush(SShareStack* pss, SDataType x, int flag)
{
    assert(pss&&((flag ==1)||(flag ==2)));

    if (flag == 1)
    {
        if (pss->top1 == pss->capacity - 2)
        {
            pss->data=AddCapacity(pss);
            //AddCapacity(pss);
        }
        pss->data[pss->top1] = x;
        pss->top1 += 2;
    }
    else
    {
        if (pss->top2 == pss->capacity - 1)
        {
            pss->data=AddCapacity(pss);
            //AddCapacity(pss);
        }
        pss->data[pss->top2] = x;
        pss->top2 += 2;
    }

}
void  SShareStackPop(SShareStack* pss, int flag)
{
    assert(pss && ((flag == 1) || (flag == 2)));

    if (flag == 1)
    {
        if (pss->top1 == 0)
            return;
        else
            pss->top1 -= 2;

    }
    else
    {
        if (pss->top2 == 1)
            return;
        else
            pss->top2 -= 2;

    }
}
int  SShareStackSize(SShareStack* pss, int flag)
{
    assert(pss && ((flag == 1) || (flag == 2)));
    if (flag == 1)
        return pss->top1/2;
    else
        return pss->top2/2;

}
SDataType  SShareStackTop(SShareStack* pss, int flag)
{
    assert(pss && ((flag == 1) || (flag == 2)));
    if (flag == 1)
        return pss->data[pss->top1-2];
    else
        return pss->data[pss->top2-2];


}
int  SShareStackEmpty(SShareStack* pss, int flag)
{
        assert(pss&&((flag ==1)||(flag ==2)));
        if (flag == 1)
            return pss->top1 == 0;
        else
            return pss->top2 == 1;

}
void testShareStack()
{
    SShareStack s;
    SShareStackInit(&s);

    SShareStackPush(&s, 3, 1);
    SShareStackPush(&s, 4, 2);
    SShareStackPush(&s, 5, 1);
    SShareStackPush(&s, 1, 2);
    SShareStackPush(&s, 5, 1);
    SShareStackPush(&s, 1, 2);

    printf("大小:%d %d\n", SShareStackSize(&s, 1), SShareStackSize(&s, 2));
    printf("栈顶:%d %d\n", SShareStackTop(&s, 1), SShareStackTop(&s, 2));
    printf("判空:%d %d\n", SShareStackEmpty(&s, 1), SShareStackEmpty(&s, 2));

    SShareStackPop(&s, 1);
    SShareStackPop(&s, 2);

    printf("大小:%d %d\n", SShareStackSize(&s, 1), SShareStackSize(&s, 2));
    printf("栈顶:%d %d\n", SShareStackTop(&s, 1), SShareStackTop(&s, 2));
    printf("判空:%d %d\n", SShareStackEmpty(&s, 1), SShareStackEmpty(&s, 2));

    SShareStackDestory(&s,1);
    SShareStackDestory(&s, 2);
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_41035588/article/details/81750931

智能推荐

【Python】完美解决Pycharm网站无法访问问题_Veni的博客-程序员信息网

解决Pycharm网站无法访问问题在我们输入网站:https://www.jetbrains.com/时会出现如下问题:无法访问这个网站嗯…无法访问此页面原因:因为你之前有安装过破解版pycharm,同时修改过host 文件,阻止劫持了官网链接。修改方法:修改hosts文件未修改前的文件如下:找到对应的网址一行,并使用 # 注释掉这一行:SO,打开网址重新试一下吧。...

解决:PHP Fatal error: Uncaught Swoole\Error: operation not support (reactor is not ready)_weixin_44694538的博客-程序员信息网

报这个错是因为没有用协程方式运行脚本,而直接用了php运行,需要在代码外面套个go(function(){ …这里写内容},才能正常运行!&lt;?phpclass AysMysql{ public $dbSource = ""; public $dbConfig = []; public function __construct() {...

linux 日志追踪 tail 命令_tail追踪日志_树下水月的博客-程序员信息网

tail -f 与tail F 与tailf三者区别tail -f 等于--follow=descriptor,根据文件描述进行追踪,当文件改名或删除后,停止追踪。tail -F 等于 --follow=name ==retry,根据文件名字进行追踪,当文件改名或删除后,保持重试,当有新的文件和他同名时,继续追踪tailf 等于tail -f -n 10(tail -f或-F默认...

Qt 4.8.6 PCL 1.8.0 VS 2010 联合编译常见错误_weixin_33708432的博客-程序员信息网

在Qt和PCL联合编译的过程中,会出现各种各样的错误,解决这些错误的过程真是痛苦万分,所以总结一些常见错误方便自己也方便他人。比如我们要编译PCL1.8.0中的apps中的point_cloud_editor这个应用时,可能会遇到如下错误:1&gt;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\...

Win7保护敏感的私人文件文件加密方法(不用软件)_johnny710vip的博客-程序员信息网

每个人的电脑里多少都会有些敏感的私人文件或者是重要的商业资料,一般都会用些技术手段将文件等保护起来不让别人看到,尤其是在电脑会被被他人使用的环境下,保护数据就更显重要。电脑上的常用保护手段无非就是加密,不过加密方法既可以很简单也可以很复杂。最简单的方法就是把文件夹设置为隐藏属性,不怎么懂电脑的人在这一招面前就基本被挡在门外;复杂一点的可以借助专业的加密软件甚至是硬件加密。Win7时代,微软

随便推点

MyBatis:Mapper 代理实现自定义接口_拾荒追逐者的博客-程序员信息网

目录1、环境搭建2、新建数据表3、创建对应的实体类 User4、创建 MyBatis 的配置文件 config.xml(文件名可自定义)5、自定义接口(Mapper 代理的形式实现)1.创建接口。2.创建 UserRepository.xml,定义接口方法对应的 SQL 语句。statement 标签根据 SQL 执行的业务可选择 insert、delete、update、select。3.在 config.xml 中注册 UserRepository.xml。4.测试1、环境搭建搭建环境,创建 Ma

多媒体计算机技术应用,谈谈多媒体计算机技术在教学中的应用_kpbs的博客-程序员信息网

1.多媒体技术在教学中的应用情况1.1在教学中应用多媒体技术的必要性。现在的教学媒体种类很多,其性能和特点各异,在教学内容上的表现上都存在这样或那样的局限性,也就是说任何一种单一的媒体都不可能很好地面对整个教学过程。作为一个完整的课堂教学,往往是有多个基本教学活动组成,当一种媒体的传递不能满足要求时,其他媒体可以进行补充。因此,需要对性能各异的教学媒体进行优化组合,使其在教学过程中扬长避短,交互应...

PBRT_V2 总结记录 <8> Primitive 和 Intersection_aa20274270的博客-程序员信息网

Primitive 类class Primitive : public ReferenceCounted {public: // Primitive Interface Primitive() : primitiveId(nextprimitiveId++) { } virtual ~Primitive(); virtual BBox WorldBound() const = 0;...

c语言char数组指针,C中char数组与char指针的区别是什么?_big maomi的博客-程序员信息网

冉冉说C中char数组与char指针的区别是什么?C99 N 1256草稿字符串文字有两种不同的用法:初始化char[]:charc[]="abc";这是“更神奇的”,并在6.7.8/14“初始化”中作了描述:字符类型的数组可以由字符串文字初始化,也可以用大括号括起来。字符串文字的连续字符(包括如果有空间或数组大小未知时终止空字符)初始化数组的元素。所以这只是一条捷径:charc[]=...

PyCharm创建Django项目_0319AUG的博客-程序员信息网

PyCharm创建Django项目1.创建虚拟环境首先创建一个新文件夹在PyCharm终端中切换到这个文件夹,输入 python -m venv 环境名 创建虚拟环境此时文件夹下出现了名为DjangoPractice的文件夹2.激活虚拟环境在终端中输入 环境名\Scripts\activate 激活环境,要停止虚拟环境可以输入deactivate3.安装Django激活条件下输入 pip install django4.在Django下创建项目...

解决TIME_WAIT过多造成的问题_state time_wait_小师兄.的博客-程序员信息网

1、 time_wait的作用:TIME_WAIT状态存在的理由:1)可靠地实现TCP全双工连接的终止 在进行关闭连接四次挥手协议时,最后的ACK是由主动关闭端发出的,如果这个最终的ACK丢失,服务器将重发最终的FIN,因此客户端必须维护状态信息允许它重发最终的ACK。如果不维持这个状态信息,那么客户端将响应RST分节,服务器将此分节解释成一个错误(在java中会抛出conne...

推荐文章

热门文章

相关标签