http://blog.csdn.net/zhaojinjia/article/details/12649823
面試官當時只給了一個小時的時間,只寫了一個鏈表反轉的程序還問了其他一些,列舉下來,希望網友看看下面,有新思路,請交流一下,謝謝。
1:實現帶頭結點的鏈表反轉問題
兩種方法:遞歸和非遞歸實現
[cpp] view plaincopyprint?
- struct ListNode
- {
- int m_nKey;
- ListNode* m_pNext;
- };
- //非遞歸實現
- ListNode* ListReverse(ListNode* pHead)
- {
- if ( !pHead->m_pNext )
- return pHead; //如果鏈表只有頭結點,直接返回頭結點
- ListNode *p1 = pHead->m_pNext;
- ListNode *p2 = p1->m_pNext;
- ListNode *p3;
- p1->m_pNext = NULL; //這一步我面試時寫程序落下了------注意一下
- while ( p2 )
- {
- p3 = p2->m_pNext; //先保存p2的next指針,防止丟失
- p2->m_pNext = p1; //修改p2的next指針,改爲指向p1
- p1 = p2; //p1向前移動
- p2 = p3; //p2向前移動
- }
- pHead->m_pNext = p1;
- return pHead;
- }
- //遞歸求鏈表反轉,返回值當前鏈表的最後一個結點
- ListNode* RecursiveListReverse(ListNode* pNode, ListNode*& pHead)
- {
- if ( !pNode ) //當沒有元素時處理
- {
- return pNode;
- }
- if (!pNode->m_pNext) //噹噹前結點爲最後一個結點時,找到頭結點,固定不動
- {
- pHead->m_pNext = NULL;
- pHead = pNode;
- return pNode;
- }
- else
- {
- ListNode* temp = RecursiveListReverse(pNode->m_pNext, pHead);
- temp->m_pNext = pNode;
- temp = pNode;
- return temp;
- }
- }
- void Traverse(ListNode* pHead)
- {
- ListNode* pTemp = pHead->m_pNext;
- cout <<"output the list: ";
- if (!pTemp)
- {
- cout <<"空鏈表"<<endl;
- return;
- }
- while (pTemp)
- {
- cout << pTemp->m_nKey <<" ";
- pTemp = pTemp->m_pNext;
- }
- cout << endl;
- }
- //創建一個帶頭結點的鏈表
- ListNode* CreateList()
- {
- cout<<"輸入空格間隔,-1爲結束表示 "<<endl;
- ListNode* pHead = new ListNode; //建一個頭結點
- pHead->m_pNext = NULL;
- ListNode* p = pHead;
- int data;
- while ( cin>>data && data!=-1 )
- {
- ListNode* pNew = new ListNode;
- pNew->m_nKey = data;
- pNew->m_pNext = NULL;
- p->m_pNext = pNew;
- p = p->m_pNext;
- }
- return pHead;
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- ListNode* pHead = CreateList(); //建立
- Traverse(pHead); //輸出
- pHead = ListReverse(pHead); //鏈表反轉
- Traverse(pHead); //輸出
- RecursiveListReverse(pHead->m_pNext,pHead->m_pNext); //遞歸鏈表反轉
- Traverse(pHead);
- return 0;
- }
2:一個數組長度爲N,且每個元素的範圍是1到N+2,且不重複出現,那麼1到N+2中肯定會有兩個數字沒有出現,要求用時間複雜度爲O(n),空間複雜度爲O(1)找出來。
利用解方程思想:X+Y=一數, X*Y=一數,可求出X和Y,但是當N較大時,這個方法不可取,求高效方法
3:虛擬內存(虛擬存儲器)
背景:常規存儲器管理方式的特徵:一次性和駐留性。
虛擬內存提出原因:1:有些作業很大,無法一下全部裝入內存;2:作業量很大,內存無法容納所有這些作業,只能將少數作業裝入內存,而將其他大量作業留在外存上。
虛擬內存是從邏輯上擴充內存容量解決問題的。
定義:具有請求調入功能和置換功能,能從邏輯上對內存容量進行擴充的一種存儲系統。其邏輯容量由內存容量和外存容量之和所決定,其運行速度接近內存速度。
理論依據--->時間局部性:如果程序某條指令被指向,則不久以後該指令會再次執行;如果某數據被訪問,則不久可能會被再次訪問。原因:程序中存在大量循環操作。空間侷限性:一旦訪問了某個存儲單元,不久後,其附近的存儲單元也將被訪問,由於程序一般是順序執行。
實現方法:有兩種 分頁請求系統 請求分段系統-------重點
虛擬存儲器的特徵: 多次性、對換性、虛擬性
頁面置換算法:最佳置換算法、先進先出頁面置換算法、LRU置換算法、clock置換算法、
4:存儲器管理
存儲層次至少應具有三級:CPU寄存器、主存(高速緩存,主存,磁盤緩存)、輔存。
用戶源程序到內存中可執行程序分兩步:編譯(將用戶源代碼編譯成若干個目標模塊),鏈接(將目標模塊以及所需要的庫函數鏈接,形成完整裝入模塊),裝入(完整模塊裝入內存)
程序裝入方式:絕對裝入、可重定位裝入、動態運行時裝入
程序鏈接方式:靜態鏈接、裝入時動態鏈接、運行時動態鏈接
連續分配方式:單一連續分配、固定分區分配、動態分區分配、動態重定位分區分配
內存管理方式:基本分頁存儲管理方式、基本分段存儲管理方式、段頁式存儲管理方式
5:文件管理
6:OSI七層協議,網絡層有哪些協議,TCP/Ip協議
7:已知有大量字符串,找出可以唯一標識每個字符串的前綴
例如:字符串爲:abe、adef、aeg、ebg,那麼它們的唯一標識前綴分別爲:ab、ad、ae、e;
方法一:按照字符順序排序,通過與其前後字符串比較計算其唯一標識前綴;
方法二:建立trie樹
8:static virtual 類大小問題
[cpp] view plaincopyprint?
- class A
- {
- int a;
- static int b;
- virtual void f();
- static void g();
- void h();
- };
計算sizeof(A)=8
9:未排序的兩個數組合併成一個數組。
求更高效方法
方法一:將兩數排序,用二路歸併進行處理
方法二: