備戰秋招——算法與數據結構(2)

在這裏插入圖片描述

● 請說一說你理解的stack overflow,並舉個簡單例子導致棧溢出

參考回答:
棧溢出概念:
棧溢出指的是程序向棧中某個變量中寫入的字節數超過了這個變量本身所申請的字節數,因而導致棧中與其相鄰的變量的值被改變。

棧溢出的原因:

  1. 局部數組過大。當函數內部的數組過大時,有可能導致堆棧溢出。局部變量是存儲在棧中的,因此這個很好理解。解決這類問題的辦法有兩個,一是增大棧空間,二是改用動態分配,使用堆(heap)而不是棧(stack)。

  2. 遞歸調用層次太多。遞歸函數在運行時會執行壓棧操作,當壓棧次數太多時,也會導致堆棧溢出。

  3. 指針或數組越界。這種情況最常見,例如進行字符串拷貝,或處理用戶輸入等等。

棧溢出例子:

#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[]) {
char buf[256];
strcpy(buf,argv[1]);
printf("Input:%s\n",buf);
return 0;
}

上述代碼中的strcpy(buf,argv[1]);這一行發生了緩衝區溢出錯誤,因爲源緩衝區內容是用戶輸入的。

● 請你回答一下棧和堆的區別,以及爲什麼棧要快

參考回答:
堆和棧的區別:
堆是由低地址向高地址擴展;棧是由高地址向低地址擴展

堆中的內存需要手動申請和手動釋放;棧中內存是由OS自動申請和自動釋放,存放着參數、局部變量等內存

堆中頻繁調用malloc和free,會產生內存碎片,降低程序效率;而棧由於其先進後出的特性,不會產生內存碎片

堆的分配效率較低,而棧的分配效率較高

棧的效率高的原因:

棧是操作系統提供的數據結構,計算機底層對棧提供了一系列支持:分配專門的寄存器存儲棧的地址,壓棧和入棧有專門的指令執行;而堆是由C/C++函數庫提供的,機制複雜,需要一些列分配內存、合併內存和釋放內存的算法,因此效率較低。

● 手寫代碼:兩個棧實現一個隊列

參考回答:

class Solution
{
public:
void push(int node) {
stack1.push(node);
}
int pop() {
if(stack2.size()!=0){
int tmp = stack2.top();
stack2.pop();
return tmp;
}
else{
while(stack1.size()!=0){
int tmp = stack1.top();
stack1.pop();
stack2.push(tmp);
}
return pop();
}
}
 
 
private:
stack<int> stack1;
stack<int> stack2;
 }

● 請你來說一下堆和棧的區別

參考回答:
1)申請方式:
棧由系統自動分配和管理,堆由程序員手動分配和管理。

2)效率:

棧由系統分配,速度快,不會有內存碎片。

堆由程序員分配,速度較慢,可能由於操作不當產生內存碎片。

3)擴展方向

棧從高地址向低地址進行擴展,堆由低地址向高地址進行擴展。

4)程序局部變量是使用的棧空間,new/malloc動態申請的內存是堆空間,函數調用時會進行形參和返回值的壓棧出棧,也是用的棧空間。

● 請你說一說小根堆特點

參考回答:
堆是一棵完全二叉樹(如果一共有h層,那麼1~h-1層均滿,在h層可能會連續缺失若干個右葉子)。
1)小根堆

若根節點存在左子女則根節點的值小於左子女的值;若根節點存在右子女則根節點的值小於右子女的值。

2)大根堆

若根節點存在左子女則根節點的值大於左子女的值;若根節點存在右子女則根節點的值大於右子女的值。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章