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

那誰的技術博客

感興趣領域:高性能服務器編程,存儲,算法,Linux內核
隨筆 - 210, 文章 - 0, 評論 - 1183, 引用 - 0
數據加載中……

另類的鏈表數據結構以及算法

一般情況下,我們使用鏈表無非就是在鏈表結點中保存該鏈表中下一個元素的指針.如果為了刪除方便,可能需要保存前一個元素的指針,也就是雙向鏈表,這樣在刪除一個結點的時候就可以很快的定位到前面和后面的結點,并且改變它們相應的指向.在這些操作里面,指向鏈表元素的指針無疑是最關鍵的數據.

考慮這樣一個問題,如果兩個進程進行通信,A進程負責管理鏈表,B進程向A進程發出分配或者刪除鏈表元素的請求.這種情況下,像上面所描述的那樣A進程直接向B進程返回鏈表元素的指針是不能做到的了,很自然的,可以想到返回另一個key標示該鏈表元素.但是,當需要查找或者刪除該鏈表元素的時候,就不能像上面那樣馬上定位到鏈表元素的位置了,需要遍歷整個鏈表.原來常量級時間復雜度的算法,在使用情形變換了之后變成了O(n)級別的復雜度.

可以找到別的辦法來解決這個問題.第一可以返回一個key標示該鏈表元素,第二保證了時間的復雜度,在這里需要定義一種新的數據結構和算法來解決這個問題.

首先,我們使用一個數組,數組中的元素是指向鏈表元素的指針,而指針的索引則是每個鏈表元素的id,這樣,通過id就可以馬上定位到對應的鏈表元素.
但是這里又會出現另一個問題,該id是從零開始的,假如在一段時間之后,需要分配一個新的鏈表元素,如何知道數組中的哪個位置是可以分配的?在這里,使用了一個整型數據的數組,數組中的每個元素是該id對應的鏈表元素在鏈表中下一個結點的id(有點拗口).我們使用兩個鏈表頭,一個將已經使用的鏈表元素id連接起來,另一個則將未使用的鏈表元素id連接起來.于是,在程序初始化的時候,未使用的鏈表中保存了所有的id,而已經使用的鏈表為空.每次分配了一個新的鏈表元素,將它的id放在使用鏈表的最開始;而每次釋放一個鏈表元素,將它的id放到未使用的鏈表頭部.
同時,改變原先鏈表元素的定義,在該結構體中,保存的不再是指針,而是鏈表中前一個元素的數組索引id.而它的下一個元素id則保存在上面的那個數組中.

如果上面我的解釋還不夠明白,可以看看下面的代碼:

#include 
<stdio.h>

#define LIST_NODE_NULL -1
#define ARRAY_SIZE 200

/* 鏈表元素定義 */
typedef 
struct list_node
{
    
int prev;   /* 下一個鏈表元素在list_array中的id */
}list_node;

/* 存放鏈表元素指針的數組 */
list_node
* list_array[ARRAY_SIZE];
/* 未使用鏈表的頭結點id */
int top_of_free;
/* 已使用鏈表的頭結點id */
int top_of_used;
/* 保存鏈表下一個元素結點id的鏈表 */
int next_list[ARRAY_SIZE];

void init_list()
{
    
int i;

    
for (i = 0; i < ARRAY_SIZE; ++i)
    {
        list_array[i] 
= NULL;
        
/* 初始時,next_list中每個結點的值都是下一個id */
        next_list[i] 
= i + 1;
    }

    
/* 最后一個結點是空 */
    next_list[i 
- 1= LIST_NODE_NULL;

    top_of_free 
= 0;
    top_of_used 
= LIST_NODE_NULL;
}

int alloc_list_node()
{
    
int id;
    
    
/* 從未使用鏈表頭部取出一個id */
    id 
= top_of_free;

    
if (LIST_NODE_NULL == id)
    {
        
return LIST_NODE_NULL;
    }

    
/* 未使用鏈表頭結點往下走一步 */
    top_of_free 
= next_list[top_of_free];

    
if (NULL == list_array[id])
    {
        list_array[id] 
= (list_node*)malloc(sizeof(list_node));
        
if (NULL == list_array[id])
        {
            
return LIST_NODE_NULL;
        }
    }

    
if (LIST_NODE_NULL == top_of_used)
    {
       
next_list[id] = top_of_used; 
        top_of_used = id;

    }
    
else
    {
        
/* 修改prev和next */ 
        list_array[top_of_used]
->prev = id;
        list_array[id]
->prev = LIST_NODE_NULL;

        next_list[id] 
= top_of_used;
        top_of_used 
= id;
    }

    
return id;
}

void free_list_node(int id)
{
    
int prev, next;

    prev 
= list_array[id]->prev;
    next 
= next_list[id];

    
/* 修改next和prev */
    if (
LIST_NODE_NULL != prev)
    {
        next_list[prev] 
= next_list[id];
    }
    
if (LIST_NODE_NULL != next && NULL != list_array[next])
    {
        list_array[next]
->prev = prev;
    }

    
if (id == top_of_used)
    {
        top_of_used 
= next_list[id];
    }

    
/* 將鏈表id返回到free鏈表頭部并且修改free鏈表頭結點 */
    next_list[id] 
= top_of_free;
    top_of_free 
= id;
}

int main()
{
    
int id;

    init_list();

    id 
= alloc_list_node();
    free_list_node(id);

    
return 0;
}



這個想法很巧妙,有效的避免了查找和刪除數組元素帶來的開銷.我不知道具體的出處在哪里,如果您知道,勞煩告訴我一聲:)


posted on 2009-03-22 19:14 那誰 閱讀(4526) 評論(7)  編輯 收藏 引用 所屬分類: 算法與數據結構

評論

# re: 另類的鏈表數據結構以及算法  回復  更多評論   

如果我沒理解錯誤的話:
1 這個應該是靜態鏈表的變形。
2 示例程序似乎有些地方有問題.
(1)分配算法里邊的:
if (LIST_NODE_NULL == top_of_used)
{
top_of_used = id;
}
是否應該改為:
if (LIST_NODE_NULL == top_of_used)
{
next_list[id] = top_of_used;
top_of_used = id;

}
(2)釋放函數:
next_list[prev] = next_list[next_list[id]];
if (NULL != list_array[next])
{
list_array[next]->prev = prev;
}
next_list[prev]和list_array[next]都有可能造成數組越界。

另外,這個next_list[prev] = next_list[next_list[id]];是否應該改為
next_list[prev] = next_list[id]?
2009-03-27 13:31 | capable

# re: 另類的鏈表數據結構以及算法  回復  更多評論   

感謝指出錯誤,已經做了修改了.
2009-03-27 19:03 | 那誰

# re: 另類的鏈表數據結構以及算法  回復  更多評論   

別客氣,應該的。
從你的博客,我學到了不少東西,希望能夠在這里看到更多你的大作。
2009-03-27 22:14 | capable

# re: 另類的鏈表數據結構以及算法  回復  更多評論   

為什么不直接使用鏈表節點指針作為key呢?
2009-03-28 15:22 | t

# re: 另類的鏈表數據結構以及算法  回復  更多評論   

應該是 Justin Heyes-Jones 在 A* Algorithm code 中的 fast simple allocator 使用的結構
http://code.google.com/p/a-star-algorithm-implementation/downloads/list
2009-04-11 01:48 | alan5281

# re: 另類的鏈表數據結構以及算法  回復  更多評論   

申請新結點空間后,應該初始化結點,否則釋放時會出現問題。
list_array[identity] = new list_node;
if(NULL == list_array[identity])
{
return(list_node_null);
}
list_array[identity]->prev = list_node_null;
2009-06-03 08:59 | zuima

# re: 另類的鏈表數據結構以及算法  回復  更多評論   

算法導論10.3介紹了這種用法,包括后面提到的用兩個鏈表來維護用過的和為用過的節點
2010-08-22 02:00 | Dbger
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            欧美一区二区三区四区在线| 牛牛国产精品| 亚洲欧美在线磁力| 亚洲乱码国产乱码精品精可以看 | 一区二区三区久久久| 亚洲人午夜精品| 亚洲日韩第九十九页| 亚洲国产美女| 亚洲每日更新| 国产精品99久久99久久久二8 | 一区二区三区www| 99精品国产在热久久婷婷| 亚洲每日在线| 一本一本久久| 欧美一区二区三区视频免费| 久久精品99国产精品| 久久伊人精品天天| 欧美精品1区2区3区| 欧美日韩成人免费| 欧美国产一区视频在线观看| 91久久精品国产91久久性色| 亚洲成人在线视频网站| 在线成人www免费观看视频| 欧美精品激情在线| 免费人成精品欧美精品| 欧美日韩一本到| 好看的av在线不卡观看| 亚洲精品黄网在线观看| 午夜在线电影亚洲一区| 亚洲成色777777女色窝| 亚洲欧美综合精品久久成人| 久久伊人精品天天| 国产美女精品视频免费观看| 18成人免费观看视频| 亚洲综合欧美| 亚洲激情成人网| 亚洲欧美日韩一区二区在线| 女主播福利一区| 韩国av一区二区三区| 亚洲欧美国产视频| 亚洲精品国久久99热| 久久九九免费视频| 国产精品五月天| 99国产麻豆精品| 欧美激情一区二区三区蜜桃视频 | 欧美大片18| 欧美在线视频导航| 国产精品视频免费观看| 一区二区三区欧美亚洲| 欧美电影在线观看完整版| 性色av一区二区怡红| 国产精品久久久久久模特 | 国产一区二区| 欧美在线不卡视频| 亚洲在线视频观看| 国产精品久久久久av免费| 亚洲少妇在线| 亚洲美女免费精品视频在线观看| 蜜桃av一区二区| 亚洲激情自拍| 91久久夜色精品国产九色| 欧美 日韩 国产一区二区在线视频| 有坂深雪在线一区| 免费在线观看精品| 久久综合网hezyo| 亚洲国产成人精品视频| 欧美v国产在线一区二区三区| 久久久精品午夜少妇| 在线电影一区| 欧美国产日本在线| 美女视频黄免费的久久| 久久免费少妇高潮久久精品99| 中日韩男男gay无套| 欧美午夜不卡在线观看免费| 亚洲在线成人精品| 午夜日韩在线观看| 在线成人欧美| 亚洲国产日韩一级| 欧美四级电影网站| 欧美一区=区| 久久激情网站| 亚洲精选国产| 亚洲影院色无极综合| 韩国在线一区| 亚洲高清精品中出| 欧美视频在线观看一区| 欧美一区二区三区四区在线| 久久精品人人做人人爽电影蜜月| 亚洲国产精品尤物yw在线观看| 91久久午夜| 国产亚洲精品久久久| 欧美大色视频| 国产精品亚洲成人| 欧美黑人国产人伦爽爽爽| 欧美日韩在线播放一区| 久久久久99| 欧美日本国产在线| 久久精品亚洲精品国产欧美kt∨| 老司机免费视频久久| 正在播放亚洲| 久久久九九九九| 在线一区观看| 久久影院亚洲| 香蕉久久夜色精品| 久热成人在线视频| 欧美在线视屏| 国产精品hd| 亚洲国产精品久久久久| 国产精品美女www爽爽爽| 久久精品国产欧美激情| 欧美黑人多人双交| 理论片一区二区在线| 欧美午夜剧场| 亚洲欧洲日韩女同| 在线观看三级视频欧美| 亚洲欧美激情四射在线日| 日韩视频不卡| 麻豆av一区二区三区久久| 欧美一区中文字幕| 欧美午夜剧场| 日韩一级黄色av| 亚洲人成在线影院| 久久久噜噜噜久噜久久| 欧美亚洲综合在线| 欧美日韩在线三区| 亚洲精品国产精品国自产观看| 在线观看国产精品网站| 羞羞答答国产精品www一本| 亚洲图片在线观看| 欧美美女操人视频| 亚洲国产影院| 亚洲人成网站色ww在线| 久久久久久一区二区| 久久爱www久久做| 国产精品久久久久久久久久免费看 | 国产在线国偷精品产拍免费yy| 亚洲日本视频| 国内精品久久久久伊人av| 亚洲素人在线| 亚洲欧美日韩人成在线播放| 欧美精品一区二区蜜臀亚洲| 欧美激情一级片一区二区| 亚洲国产欧美在线人成| 久久综合色88| 亚洲精品123区| 一本一本久久a久久精品综合麻豆 一本一本久久a久久精品牛牛影视 | 久热re这里精品视频在线6| 久久精品国产亚洲一区二区| 国产精品久久久久久久久久久久久久 | 国产精品免费一区豆花| 亚洲性夜色噜噜噜7777| 欧美一区二区免费| 国产女人aaa级久久久级| 亚洲欧美一区二区视频| 久久久久久久综合日本| 怡红院精品视频在线观看极品| 久久综合图片| 99av国产精品欲麻豆| 亚洲欧美日韩视频二区| 国产日韩欧美日韩| 久久久久青草大香线综合精品| 欧美成人福利视频| 99ri日韩精品视频| 国产精品扒开腿做爽爽爽软件| 亚洲一区二区三区乱码aⅴ| 久久精品综合一区| 在线观看日韩一区| 欧美日韩中文字幕在线| 亚洲综合精品自拍| 免费成人在线观看视频| 99精品视频一区| 国产欧美在线播放| 欧美韩日高清| 欧美怡红院视频一区二区三区| 欧美激情综合| 校园春色国产精品| 亚洲日本中文字幕区| 国产精品入口| 欧美凹凸一区二区三区视频| 亚洲天堂av在线免费观看| 免费亚洲一区二区| 欧美亚洲免费在线| 日韩图片一区| 激情久久久久| 欧美激情视频在线免费观看 欧美视频免费一| 久久久久国内| 亚洲国产小视频| 国产美女精品免费电影| 欧美va天堂在线| 小黄鸭精品密入口导航| 亚洲黄一区二区三区| 久久精品青青大伊人av| 一区二区三区免费在线观看| 1000部精品久久久久久久久| 欧美日韩在线播放| 欧美成人自拍视频| 久久久天天操| 久久激情视频久久| 亚洲在线一区二区| 日韩一区二区电影网|