青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-80  評論-24  文章-0  trackbacks-0
面試經(jīng)典問題:
“逆置一個(gè)單鏈表”
鏈表結(jié)構(gòu)為:
 
1 typedef struct node
2 {
3       int data;
4       struct node *next;
5 } NODE;

由于題目限制比較少,所以就需要仔細(xì)考慮,鏈表是否有環(huán)?如果鏈表有小環(huán)那么鏈表將不可逆置,因?yàn)榄h(huán)的入口節(jié)點(diǎn)有兩個(gè)前驅(qū)節(jié)點(diǎn)。所有首先應(yīng)該判斷鏈表是否有小環(huán),如果沒有小環(huán)才能對鏈表進(jìn)行逆置。而如何判斷鏈表是否有環(huán)?一種方法是用一個(gè)指針遍歷鏈表,每遍歷一個(gè)節(jié)點(diǎn)便對節(jié)點(diǎn)做標(biāo)記,如果節(jié)點(diǎn)走到NULL,則說明沒有環(huán),如果遇到了已經(jīng)做過標(biāo)記的節(jié)點(diǎn),則說明有環(huán),且這個(gè)做標(biāo)記的節(jié)點(diǎn)就是入口。但是如果不允許對節(jié)點(diǎn)做標(biāo)記該怎么辦呢?另外一種方法是對每個(gè)節(jié)點(diǎn)的地址做hash,每次訪問一個(gè)節(jié)點(diǎn)的時(shí)候都查看hash表,如果該節(jié)點(diǎn)的地址不在hash表中,則說明該節(jié)點(diǎn)未被訪問,直到遇到NULL或者遇到某個(gè)節(jié)點(diǎn)在hash表中有記錄,則該節(jié)點(diǎn)則是環(huán)的入口。該算法同樣有很大的弊病,需要大量內(nèi)存,因?yàn)楣?jié)點(diǎn)的地址是32位的。下面提供第三種方法:采用兩個(gè)指針(假設(shè)為p1,p2),初始情況下都指向鏈表頭,之后p2每次走2步,p1每次走1步,當(dāng)p1和p2相交的時(shí)候則說明有環(huán),否則當(dāng)p2走到NULL的時(shí)候則說明無環(huán),證明也比較簡單。那么如何找到環(huán)的入口點(diǎn)呢?這里提供一種方法:當(dāng)確定有環(huán)后,p2在相交處,p1重新指向鏈表開頭,然后每次兩個(gè)指針都各走一步,這樣兩個(gè)指針再次相遇的時(shí)候便是環(huán)的入口處。證明如下:
假設(shè)從鏈表頭到環(huán)的入口長度為l,環(huán)的周長為r,p1和p2相遇的點(diǎn)距離環(huán)入口為x
則我們有以下結(jié)論:
1、第一次相交的時(shí)候p1還沒有走完整條鏈表,而p2則在鏈表的環(huán)內(nèi)轉(zhuǎn)了n圈
2、第一次相交的時(shí)候p2走的距離是p1的兩倍,因?yàn)閜2每次走兩步而p1每次走一步
這樣我們就得到如下公式:
2(x + l) = l + x + nr
則可以得到l = nr - x
這樣我們將p1重新放到鏈表頭開始走,那么當(dāng)p1節(jié)點(diǎn)走了l距離的時(shí)候,可以知道p2也走了l距離,而l = nr - x,所以p2走了nr - x,而p2從相交點(diǎn)開始走的,該點(diǎn)距離環(huán)入口處為x,這樣可以知道當(dāng)p2走了nr - x步后正好就到了環(huán)的入口,而p1此時(shí)也正在環(huán)的入口,可以知道p1和p2正好相遇,證畢。

下面一段代碼是用來判斷鏈表是否有環(huán)的,包括大環(huán)和小環(huán):

 1 node *list_isloop(node *head) {
 2     if (head == NULL) return head;
 3     node *p1 = head, *p2 = head;
 4     do {
 5         p2 = p2->next;
 6         if (p2 == NULL || p2 == head) return p2;
 7         p2 = p2->next;
 8         if (p2 == NULL || p2 == head) return p2;
 9         p1 = p1->next;
10     } while (p1 != p2);
11     p1 = head;
12     while (p1 != p2) { p1 = p1->next; p2 = p2->next; }
13     return p2;
14 }

其實(shí)對于單鏈表的操作,絕大部分都需要先判斷鏈表是否為空,然后判斷鏈表是否呦環(huán),有大環(huán)和有小環(huán)在有寫問題的處理方式未必一樣,比如對于鏈表逆置,鏈表為空、或者鏈表有大環(huán),鏈表都可以正常被逆置,而如果是有小環(huán)的鏈表,則鏈表不可被逆置。
下面看鏈表逆置的代碼,其中調(diào)用了上面判斷鏈表是否有環(huán)的函數(shù):

 1 node *list_reverse(node *head) {
 2     if (head == NULL || head->next == NULL) return head;
 3     node *entry = list_isloop(head);
 4     if (entry != NULL && entry != head) return NULL;
 5     node *p1 = head, *p2 = p1->next, *p3 = p2->next;
 6     p1->next = NULL;
 7     while (p3 && p3 != head) {
 8         p2->next = p1; 
 9         p1 = p2;
10         p2 = p3;
11         p3 = p3->next;
12     }
13     p2->next = p1;
14     return p2;
15 }

下面一段代碼是用來對單鏈表測長的,也許要對單鏈表判斷是否有環(huán):

 1 int list_len(node *head) {
 2     int len = 0;
 3     node *p = head, *entry = NULL;
 4     if (head == NULL) return 0;
 5     entry = list_isloop(head);
 6     while (p != entry) { ++len; p = p->next; }
 7     if (entry != NULL)
 8         do { ++len; p = p->next; } while (p != entry);
 9     return len;
10 }

而下面一段代碼是用來判斷兩個(gè)單鏈表是否相交的,該問題有點(diǎn)復(fù)雜:
首先,如果其中任意一條鏈表為空,則不可能相交
其次,如果兩個(gè)鏈表都沒有環(huán),則判斷鏈表的尾元素是否相同
再次,如果兩個(gè)鏈表一個(gè)呦環(huán),一個(gè)無環(huán),則不可能相交
最后,如果兩個(gè)鏈表均有環(huán),則從其中一個(gè)入口處開始走一圈,如果中間和另一環(huán)的入口相遇則說明兩鏈表相交

 1 int list_intersecting(node *head1, node *head2) {
 2     if (head1 == NULL || head2 == NULL) return 0;
 3     node *entry1 = list_isloop(head1);
 4     node *entry2 = list_isloop(head2);
 5     //兩個(gè)鏈表都沒有環(huán)
 6     if (entry1 == NULL && entry2 == NULL) {
 7         while (head1->next != NULL) head1 = head1->next;
 8         while (head2->next != NULL) head2 = head2->next;
 9         if (head1 == head2) return 1;
10         return 0;
11     }
12     //兩個(gè)鏈表都有環(huán)
13     else if (entry1 != NULL && entry2 != NULL) {
14         node *tmp = entry1;
15         while (tmp->next != entry1) {
16             if (tmp == entry2) return 1;
17             tmp = tmp->next;
18         }
19         if (tmp == entry2) return 1;
20     }
21     //一個(gè)有環(huán)一個(gè)無環(huán)
22     return 0;
23 }

下面是合并兩個(gè)有序鏈表,該問題也需要考慮全面,既然有序,則不需要考慮是否有環(huán),但是兩個(gè)鏈表是否都是遞增或者遞減則需要考慮,我們在此不判斷兩個(gè)鏈表一個(gè)一個(gè)遞增一個(gè)遞減的情況。下面代碼第三個(gè)參數(shù)代表鏈表單調(diào)性,flag = 0代表遞增,flag != 0代表遞減:

 1 node *list_merge(node *head1, node *head2, int flag) {
 2     if (head1 == NULL) return head2;
 3     if (head2 == NULL) return head1;
 4     flag = !!flag;
 5     node *head = NULL;
 6     if (flag == 0) {
 7         if (head1->data < head2->data) {
 8             head = head1;
 9             head->next = list_merge(head1->next, head2, flag);
10         }
11         else {
12             head = head2;
13             head->next = list_merge(head1, head2->next, flag);
14         }
15     }
16     else {
17         if (head1->data > head2->data) {
18             head = head1;
19             head->next = list_merge(head1->next, head2, flag);
20         }
21         else {
22             head = head2;
23             head->next = list_merge(head1, head2->next, flag);
24         }
25         return head;
26     }
27 }

對于將鏈表排序也有一個(gè)非常巧妙的地方,我們知道普通數(shù)組排序一般采用快排、堆排或者歸并排序,而在鏈表上卻不那么容易,因?yàn)殒湵聿荒苤苯佑盟饕齺韺ぶ?,而是采用指針地址索引,所以快排、堆排都失去了?yōu)勢,但是歸并排序卻如魚得水,而且在數(shù)組歸并排序當(dāng)中被詬病的空間復(fù)雜度O(n)在鏈表排序當(dāng)中也降為O(1)。這里面還用到了一個(gè)小技巧,就是如何找到鏈表的中間元素,這里采用兩個(gè)指針一快一慢的方法:

 1 node *list_sort(node *head, int flag) {
 2     if (head == NULL || head->next == NULL) return head;
 3     flag = !!flag;
 4     node *p1 = head, *p2 = head;
 5     while (p2 != NULL) {
 6         if ((p2 = p2->next) == NULL) break;
 7         if ((p2 = p2->next) == NULL) break;
 8         p1 = p1->next;
 9     }
10     p2 = p1->next;
11     p1->next = NULL;
12     p1 = list_sort(head, flag);
13     p2 = list_sort(p2, flag);
14     return list_merge(p1, p2, flag);
15 }

找到無環(huán)鏈表倒數(shù)第k個(gè)節(jié)點(diǎn),該問題比較簡單,只需要先設(shè)一個(gè)指針p2預(yù)先走k步,然后再讓p2每次走一步,同時(shí)在鏈表開頭也有一指針p1每次走一步,這樣,當(dāng)p2走到尾部的時(shí)候p1則恰好是倒數(shù)第k個(gè)節(jié)點(diǎn):

 1 node *list_ktailed(node *head, int k) {
 2     if (k < 0) return NULL;
 3     int i = 0;
 4     node *p1 = head, *p2 = head;
 5     for (; i < k; ++i) {
 6         if (p2 == NULL) return NULL;
 7         p2 = p2->next;
 8     }
 9     while (p2 != NULL) { p2 = p2->next; p1 = p1->next; }
10     return p1;
11 }

關(guān)于鏈表問題暫時(shí)寫到此。
posted on 2012-02-10 15:43 myjfm 閱讀(439) 評論(0)  編輯 收藏 引用 所屬分類: 筆試+面試總結(jié)
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美一区二区三区免费在线看| 牛牛国产精品| 激情一区二区| 日韩西西人体444www| 国产日韩精品一区观看| 美女视频黄 久久| 亚洲电影免费观看高清完整版在线 | 韩国欧美国产1区| 国产日韩欧美电影在线观看| 欧美日韩日本国产亚洲在线| 国产欧美日韩不卡| 欧美在线不卡| 欧美激情黄色片| 亚洲一区日韩在线| 亚洲视频www| 国产欧美日本一区二区三区| 久久精品亚洲精品| 国产视频在线观看一区 | 精品成人免费| 欧美一区二区三区四区在线观看地址 | 久久久国产视频91| 亚洲成人自拍视频| 一区二区三区久久精品| 亚洲欧洲在线一区| 一区二区三区欧美亚洲| 欧美精品国产精品| 欧美一区日韩一区| 欧美激情1区| 国产精品色在线| 日韩视频专区| 一本大道久久a久久精品综合| 久久久www成人免费毛片麻豆| 亚洲一区二区三区免费视频| 久久成人人人人精品欧| 亚洲国产一二三| 亚洲精品综合久久中文字幕| 亚洲最新在线视频| 久久综合色综合88| 老司机午夜免费精品视频| 国产精品久久久久久久久免费桃花 | 欧美伊久线香蕉线新在线| 99精品国产福利在线观看免费| 久久国产乱子精品免费女 | 欧美激情第8页| 免费欧美日韩| 亚洲欧美美女| 亚洲综合不卡| 日韩一级视频免费观看在线| 欧美在线视频日韩| 欧美久色视频| 国产一区二区三区四区五区美女 | 国产日韩欧美在线一区| 久久免费视频在线| 欧美国产三级| 欧美一区二区高清| 免费久久99精品国产自在现线| 91久久精品一区二区别| 日韩视频一区二区| 国产综合激情| 一区二区三区成人精品| 一二美女精品欧洲| 黄色国产精品一区二区三区| 亚洲三级影院| 国产精品一区二区三区四区| 久久精品中文字幕一区| 欧美顶级艳妇交换群宴| 欧美一区二区在线视频| 欧美一区二区精美| 久久不见久久见免费视频1| 免费欧美在线| 亚洲人成网站精品片在线观看| 极品裸体白嫩激情啪啪国产精品| 亚洲午夜激情免费视频| 亚洲成人影音| 欧美乱在线观看| 亚洲欧美日韩专区| 蜜臀久久99精品久久久久久9 | 欧美视频一区二| 亚洲私拍自拍| 夜夜嗨av色一区二区不卡| 亚洲一区二区三区四区中文| 亚洲人成欧美中文字幕| 久久精品国产v日韩v亚洲| 亚洲一区二区三区四区五区午夜| 亚洲日韩视频| 久久久久久色| 亚洲伦理精品| 91久久精品国产91性色| 这里只有视频精品| 99这里只有久久精品视频| 久久久久女教师免费一区| 欧美亚洲视频| 国产精品社区| 性欧美大战久久久久久久免费观看| 一本久道综合久久精品| 欧美成人高清| 亚洲国产专区校园欧美| 亚洲高清久久久| 牛牛精品成人免费视频| 欧美黑人国产人伦爽爽爽| 亚洲成人在线网| 国产一区二区久久久| 亚洲国产精品综合| 亚洲激情视频| 免费人成网站在线观看欧美高清| 久久久www成人免费毛片麻豆| 欧美四级电影网站| 亚洲夜晚福利在线观看| 亚洲欧美中文在线视频| 国产精品成人一区二区三区吃奶| 亚洲国产91| 这里只有精品视频| 国产精品网站在线| 久久精品一区蜜桃臀影院| 久久影视精品| 日韩亚洲欧美一区| 国产精品一区二区久久久| 亚洲欧美在线免费观看| 久久免费高清视频| 亚洲精选一区| 国产毛片精品视频| 久久久久久黄| 亚洲最新视频在线| 久久一区二区三区四区| 亚洲三级电影全部在线观看高清| 欧美精品一区二区高清在线观看| 亚洲美女av在线播放| 亚洲欧美精品在线观看| 国产在线观看一区| 欧美国产大片| 亚洲欧美日韩精品久久亚洲区| 久久国产精品久久w女人spa| 国产女主播一区二区三区| 先锋影院在线亚洲| 亚洲第一免费播放区| 亚洲素人在线| 国产综合精品一区| 欧美二区在线看| 亚洲欧美日韩精品一区二区| 亚洲欧美影院| 亚洲电影下载| 国产精品日韩精品欧美精品| 亚洲欧美精品suv| 亚洲第一毛片| 久久青青草原一区二区| 99精品国产福利在线观看免费| 国产精品视频最多的网站| 久久久久国产免费免费| 最新热久久免费视频| 久久精品国产精品| 一区二区三区av| 激情综合网址| 国产亚洲精品久久久| 欧美日本精品在线| 久久久精品网| 午夜精品成人在线| 一本色道久久综合精品竹菊| 久久久精品网| 欧美一级片在线播放| 在线精品亚洲一区二区| 国产精品久久久久影院色老大| 蜜臀av性久久久久蜜臀aⅴ| 亚洲一区日本| 一区二区三区 在线观看视频| 亚洲天堂偷拍| 一区二区三区四区五区视频| 国精品一区二区| 国产日韩在线视频| 国产乱码精品一区二区三| 老鸭窝91久久精品色噜噜导演| 一区二区三区高清在线| 欧美成人首页| 女同性一区二区三区人了人一| 香蕉视频成人在线观看| 欧美一区二区黄色| 香蕉免费一区二区三区在线观看| 亚洲精品国产精品国自产观看| 欧美大片在线看| 久久综合国产精品| 久久精品在线观看| 欧美一区二区三区在线观看视频 | 91久久国产综合久久蜜月精品| 国产色爱av资源综合区| 国产精品国产三级欧美二区| 久久夜精品va视频免费观看| 亚洲久色影视| 国产亚洲观看| 韩国免费一区| 亚洲国产视频一区| 亚洲毛片在线免费观看| 日韩亚洲欧美成人一区| 99国产一区| 午夜精品视频| 久久久久久色| 亚洲欧洲日本一区二区三区| 男女精品视频| 亚洲精品乱码久久久久久按摩观 | 欧美有码在线视频| 久久精品日产第一区二区三区| 久久岛国电影|