• <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>
            面對(duì)現(xiàn)實(shí),超越自己
            逆水行舟,不進(jìn)則退
            posts - 269,comments - 32,trackbacks - 0
            C++ Stack(堆棧) 是一個(gè)容器類的改編,為程序員提供了堆棧的全部功能,——也就是說實(shí)現(xiàn)了一個(gè)先進(jìn)后出(FILO)的數(shù)據(jù)結(jié)構(gòu)。
            1.empty() 堆棧為空則返回真
            2.pop() 移除棧頂元素
            3.push() 在棧頂增加元素
            4.size() 返回棧中元素?cái)?shù)目
            5.top() 返回棧頂元素

            棧可以用向量(vector)、線性表(list)或雙向隊(duì)列(deque)來實(shí)現(xiàn):
            stack<vector<int>> s1;
            stack<list<int> > s2;
            stack<deque<int>> s3;
            其成員函數(shù)有“判空(empty)” 、“尺寸(Size)” 、“棧頂元素(top)” 、“壓棧(push)” 、“彈棧(pop)”等。

            范例引自:http://blog.csdn.net/morewindows/article/details/6950881

             1 int main()  
             2 {  
             3     //可以使用list或vector作為棧的容器,默認(rèn)是使用deque的。   
             4     stack<int, list<int>>      a;  
             5     stack<int, vector<int>>   b;  
             6     int i;  
             7       
             8     //壓入數(shù)據(jù)   
             9     for (i = 0; i < 10; i++)  
            10     {  
            11         a.push(i);  
            12         b.push(i);  
            13     }  
            14   
            15     //棧的大小   
            16     printf("%d %d\n", a.size(), b.size());  
            17   
            18     //取棧項(xiàng)數(shù)據(jù)并將數(shù)據(jù)彈出棧   
            19     while (!a.empty())  
            20     {  
            21         printf("%d ", a.top());  
            22         a.pop();  
            23     }  
            24     putchar('\n');  
            25   
            26     while (!b.empty())  
            27     {  
            28         printf("%d ", b.top());  
            29         b.pop();  
            30     }  
            31     putchar('\n');  
            32     return 0;  
            33 }  
            34 

            posted @ 2012-06-05 13:16 王海光 閱讀(619) | 評(píng)論 (0)編輯 收藏
                 摘要: 本文轉(zhuǎn)自:http://blog.csdn.net/wangji163163/article/details/3539756。GetLastError()返回值意義總結(jié) 〖0〗-操作成功完成。〖1〗-功能錯(cuò)誤。〖2〗-系統(tǒng)找不到指定的文件。〖3〗-系統(tǒng)找不到指定的路徑。〖4〗-系統(tǒng)無法打開文件。〖5〗-拒絕訪問。〖6〗-句柄無效。〖7〗-存儲(chǔ)控制塊被損壞。〖8〗-存儲(chǔ)空間不足,無法處理此命令。〖9〗-存儲(chǔ)控制塊地址無效。〖10〗-環(huán)境錯(cuò)誤。
              閱讀全文
            posted @ 2012-06-05 10:58 王海光 閱讀(467) | 評(píng)論 (0)編輯 收藏
            STL Set介紹

            集合(Set)是一種包含已排序?qū)ο蟮年P(guān)聯(lián)容器。多元集合(MultiSets)和集合(Sets)相像,只不過支持重復(fù)對(duì)象,其用法與set基本相同。
            Set 又稱集合,實(shí)際上就是一組元素的集合,但其中所包含的元素的值是唯一的,且是按一定順序排列的,集合中的每個(gè)元素被稱作集合中的實(shí)例。因?yàn)槠鋬?nèi)部是通過鏈表的方式來組織,所以在插入的時(shí)候比vector 快,但在查找和末尾添加上比vector 慢。
            multiset 是多重集合,其實(shí)現(xiàn)方式和set 是相似的,只是它不要求集合中的元素是唯一的,也就是說集合中的同一個(gè)元素可以出現(xiàn)多次。

            構(gòu)造:
            explicit set(const Compare&=compare());
            如:set<int,less<int> > set1;
            less<int>是一個(gè)標(biāo)準(zhǔn)類,用于形成升序排列函數(shù)對(duì)象。降序排列是用greater<int>。
            Template<class InputIterator> set(InputIterator, InputIterator,\ const Compare&=compare());
            如:set<int ,less<int> >set2(vector1.begin(),vector1.end());
            通過指定某一預(yù)先定義的區(qū)間來初始化set對(duì)象的構(gòu)造函數(shù)。
            set(const set<Key,Compare&>);
            如:set<int ,less<int> >set3(set2);

            方法:
            1.begin() 返回指向第一個(gè)元素的迭代器
            2.clear() 清除所有元素
            3.count() 返回某個(gè)值元素的個(gè)數(shù)
            4.empty() 如果集合為空,返回true
            5.end() 返回指向最后一個(gè)元素的迭代器
            6.equal_range() 返回第一個(gè)>=關(guān)鍵字的迭代器和>關(guān)鍵字的迭代器
                  語法:
                  pair <iterator,iterator>equal_range( const key_type &key );
                  //key是用于排序的關(guān)鍵字
                  Set<int> ctr;
                  例如:
                  Pair<set<int>::iterator,set<int>::iterarot>p;
                  For(i=0;i<=5;i++) ctr.insert(i);
                  P=ctr.equal_range(2);
                  那么*p.first==2;*p.second==3;
            7.erase() 刪除集合中的元素
                  語法:
                  iterator erase( iterator i ); //刪除i位置元素
                  iterator erase( iterator start, iterator end );
                  //刪除從start開始到end(end為第一個(gè)不被刪除的值)結(jié)束的元素
                  size_type erase( const key_type &key );
                  //刪除等于key值的所有元素(返回被刪除的元素的個(gè)數(shù))
                  //前兩個(gè)返回第一個(gè)不被刪除的雙向定位器,不存在返回末尾
                  //第三個(gè)返回刪除個(gè)數(shù)
            8.find() 返回一個(gè)指向被查找到元素的迭代器
                  語法:
                  iterator find( const key_type &key );
                  //查找等于key值的元素,并返回指向該元素的迭代器;
                  //如果沒有找到,返回指向集合最后一個(gè)元素的迭代器
            9.get_allocator() 返回集合的分配器
            10.insert() 在集合中插入元素
                  語法:
                  iterator insert( iterator i, const TYPE &val ); //在迭代器i前插入val
                  void insert( input_iterator start, input_iterator end );
                  //將迭代器start開始到end(end不被插入)結(jié)束返回內(nèi)的元素插入到集合中
                  pair insert( const TYPE &val );
                  //插入val元素,返回指向該元素的迭代器和一個(gè)布爾值來說明val是否成功被插入
                  //應(yīng)該注意的是在集合(Sets中不能插入兩個(gè)相同的元素)
            11.lower_bound() 返回指向大于(或等于)某值的第一個(gè)元素的迭代器
                  語法:
                  iterator lower_bound( const key_type &key );
                  //返回一個(gè)指向大于或者等于key值的第一個(gè)元素的迭代器
            12.key_comp() 返回一個(gè)用于元素間值比較的函數(shù)
                  語法:
                  key_compare key_comp();
                  //返回一個(gè)用于元素間值比較的函數(shù)對(duì)象
            13.max_size() 返回集合能容納的元素的最大限值
            14.rbegin() 返回指向集合中最后一個(gè)元素的反向迭代器
                  示例:
                  Set<int> ctr;
                  Set<int>::reverse_iterator rcp;
                  For(rcp=ctr.rbegin();rcp!=ctr.rend();rcp++)
                  Cout<<*rcp<<” ”;
            15.rend() 返回指向集合中第一個(gè)元素的反向迭代器
            16.size() 集合中元素的數(shù)目
            17.swap() 交換兩個(gè)集合變量
                  語法:
                  void swap( set &object ); //交換當(dāng)前集合和object集合中的元素
            18.upper_bound() 返回大于某個(gè)值元素的迭代器
                  語法:
                  iterator upwer_bound( const key_type &key );
                  //返回一個(gè)指向大于key值的第一個(gè)元素的迭代器
            19.value_comp() 返回一個(gè)用于比較元素間的值的函數(shù)
                  語法:
                  iterator upper_bound( const key_type &key );//返回一個(gè)用于比較元素間的值的函數(shù)對(duì)象
            20.Set集合的并,交和差
            set_union(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));
            set_intersection(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));
            set_difference(a.begin(),a.end(),b.begin(),b.end(),insert_iterator<set<int> >(c,c.begin()));

            以下轉(zhuǎn)自:http://blog.csdn.net/wangji163163/article/details/3740948

            STL Set 交集 合集 差集

            Set是關(guān)聯(lián)容器。其鍵值就是實(shí)值,實(shí)值就是鍵值,不可以有重復(fù),所以我們不能通過set的迭代器來改變set的元素的值,set擁有和list相同的特性:當(dāng)對(duì)他進(jìn)行插入和刪除操作的時(shí)候,操作之前的迭代器依然有效。當(dāng)然刪除了的那個(gè)就沒效了。Set的底層結(jié)構(gòu)是RB-tree,所以是有序的。

               stl中特別提供了一種針對(duì)set的操作的算法:交集set_intersection,并集set_union,差集set_difference。對(duì)稱差集set_symeetric_difference,這些算法稍后會(huì)講到。

            一:set模板類的聲明。

            1 template <
            2    class Key, 
            3    class Traits=less<Key>
            4    class Allocator=allocator<Key> 
            5 >
            6 class set

            其中個(gè)參數(shù)的意義如下:

            key:要放入set里的數(shù)據(jù)類型,可以是任何類型的數(shù)據(jù)。

            Traits:這是一個(gè)仿函數(shù)(關(guān)于仿函數(shù)是什么,我后面的文章會(huì)講到)。提供了具有比較功能的仿函數(shù),來覺得元素在set里的排列的順序,這是一個(gè)可選的參數(shù),默認(rèn)的是std::less<key>,如果要自己提供這個(gè)參數(shù),那么必須要遵循此規(guī)則:具有兩個(gè)參數(shù),返回類型為bool。

            Allocator:空間配置器,這個(gè)參數(shù)是可選的,默認(rèn)的是std::allocator<key>.

            二:set里的基本操作

            我們可以通過下面的方法來實(shí)例化一個(gè)set對(duì)

            std::set<int> s;那個(gè)s這個(gè)對(duì)象里面存貯的元素是從小到大排序的,(因?yàn)橛胹td::less作為比較工具。)

            如果要想在s里面插入數(shù)據(jù),可以用inset函數(shù)(set沒用重載[]操作,因?yàn)閟et本生的值和索引是相同的)

            s.insert(3);s.insert(5).....

            因?yàn)閟et是集合,那么集合本身就要求是唯一性,所以如果要像set里面插入數(shù)據(jù)和以前的數(shù)據(jù)有重合,那么插入不成功。

            可以通過下面的方法來遍歷set里面的元素

            1 std::set<int>::iterator it = s.begin();
            2 while(it!=s.end())
            3 {
            4    cout<<*it++<<endl;//迭代器依次后移,直到末尾。
            5 }

            如果要查找一個(gè)元素用find函數(shù),it = s.find(3);這樣it是指向3的那個(gè)元素的。可以通過rbegin,rend來逆向遍歷

            1 std::set<int>::reverse_iterator it = s.rbegin();
            2 
            3 while(it!=s.rend())
            4 
            5 {cout<<*it++<<endl;}

            還有其他的一些操作在這就不一一列出了。

            三:與set相關(guān)的一組算法

            set_intersection() :這個(gè)函數(shù)是求兩個(gè)集合的交集。下面是stl里的源代碼

             1 template<class _InIt1,
             2 class _InIt2,
             3 class _OutIt> inline
             4 _OutIt set_intersection(_InIt1 _First1, _InIt1 _Last1,
             5    _InIt2 _First2, _InIt2 _Last2, _OutIt _Dest)
             6 // AND sets [_First1, _Last1) and [_First2, _Last2), using operator<
             7 for (; _First1 != _Last1 && _First2 != _Last2; )
             8    if (*_First1 < *_First2)
             9     ++_First1;
            10    else if (*_First2 < *_First1)
            11     ++_First2;
            12    else
            13     *_Dest++ = *_First1++++_First2;
            14 return (_Dest);
            15 }

                  這是個(gè)模板函數(shù),從上面的算法可以看出,傳進(jìn)去的兩個(gè)容器必須是有序的。_Dest指向輸出的容器,這個(gè)容器必須是預(yù)先分配好空間的,否則會(huì)出錯(cuò)的,返回值指向保存結(jié)果的容器的尾端的下一個(gè)位置。eg.

             1 set_union() :求兩個(gè)集合的并集,參數(shù)要求同上。
             2 
             3 std::set_difference():差集
             4 
             5 set_symmetric_difference():得到的結(jié)果是第一個(gè)迭代器相對(duì)于第二個(gè)的差集并上第二個(gè)相當(dāng)于第一個(gè)的差集。代碼:
             6 
             7 struct compare
             8 {
             9 bool operator ()(string s1,string s2)
            10 {
            11    return s1>s2;
            12 }///自定義一個(gè)仿函數(shù)
            13 };
            14 int main()
            15 {
            16 typedef std::set<string,compare> _SET;
            17 _SET s;
            18 s.insert(string("sfdsfd"));
            19 s.insert(string("apple"));
            20 s.insert(string("english"));
            21 s.insert(string("dstd"));
            22 cout<<"s1:"<<endl;
            23 std::set<string,compare>::iterator it = s.begin();
            24 while(it!=s.end())
            25    cout<<*it++<<"   ";
            26 cout<<endl<<"s2:"<<endl;
            27 _SET s2;
            28 s2.insert(string("abc"));
            29 s2.insert(string("apple"));
            30 s2.insert(string("english"));
            31 it = s2.begin();
            32 while(it!=s2.end())
            33    cout<<*it++<<"   ";
            34 cout<<endl<<endl;
            35 
            36 string str[10];
            37 string *end = set_intersection(s.begin(),s.end(),s2.begin(),s2.end(),str,compare());//求交集,返回值指向str最后一個(gè)元素的尾端
            38 cout<<"result of set_intersection s1,s2:"<<endl;
            39    string *first = str;
            40    while(first<end)
            41     cout <<*first++<<" ";
            42    cout<<endl<<endl<<"result of set_union of s1,s2"<<endl;
            43    end = std::set_union(s.begin(),s.end(),s2.begin(),s2.end(),str,compare());//并集
            44    first = str;
            45    while(first<end)
            46     cout <<*first++<<" ";
            47    cout<<endl<<endl<<"result of set_difference of s2 relative to s1"<<endl; 
            48    first = str;
            49    end = std::set_difference(s.begin(),s.end(),s2.begin(),s2.end(),str,compare());//s2相對(duì)于s1的差集
            50    while(first<end)
            51     cout <<*first++<<" ";
            52    cout<<endl<<endl<<"result of set_difference of s1 relative to s2"<<endl; 
            53    first = str;
            54    end = std::set_difference(s2.begin(),s2.end(),s.begin(),s.end(),str,compare());//s1相對(duì)于s2的差集
            55 
            56    while(first<end)
            57     cout <<*first++<<" ";
            58    cout<<endl<<endl;
            59    first = str;
            60 end = std::set_symmetric_difference(s.begin(),s.end(),s2.begin(),s2.end(),str,compare());//上面兩個(gè)差集的并集
            61    while(first<end)
            62     cout <<*first++<<" ";
            63    cout<<endl; 
            64 }
            65 
            66 set<int>   s3   ;   
            67 set<int>::iterator   iter   =   s3.begin()   ;   
            68 set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(s3,iter));   
            69 copy(s3.begin(),s3.end(),   ostream_iterator<int>(cout,"   "));


             

            posted @ 2012-06-05 10:51 王海光 閱讀(1183) | 評(píng)論 (0)編輯 收藏
                 摘要: C++ Maps & MultiMapsC++ Maps是一種關(guān)聯(lián)式容器,包含“關(guān)鍵字/值”對(duì)。 C++ Multimaps和maps很相似,但是MultiMaps允許重復(fù)的元素。 1.begin() 返回指向map頭部的迭代器 2.clear() 刪除所有元素 3.count() 返回指定元素出現(xiàn)的次數(shù)    語法...  閱讀全文
            posted @ 2012-06-04 16:57 王海光 閱讀(1848) | 評(píng)論 (0)編輯 收藏

            C++ Deque(雙向隊(duì)列)

                是一種優(yōu)化了的、對(duì)序列兩端元素進(jìn)行添加和刪除操作的基本序列容器。它允許較為快速地隨機(jī)訪問,但它不像vector 把所有的對(duì)象保存在一塊連續(xù)的內(nèi)存塊,而是采用多個(gè)連續(xù)的存儲(chǔ)塊,并且在一個(gè)映射結(jié)構(gòu)中保存對(duì)這些塊及其順序的跟蹤。向deque 兩端添加或刪除元素的開銷很小。它不需要重新分配空間,所以向末端增加元素比vector 更有效。

                實(shí)際上,deque 是對(duì)vector list 優(yōu)缺點(diǎn)的結(jié)合,它是處于兩者之間的一種容器。

            Deque 的特點(diǎn):

                (1) 隨機(jī)訪問方便,即支持[ ] 操作符和vector.at() ,但性能沒有vector 好;

                (2) 可以在內(nèi)部進(jìn)行插入和刪除操作,但性能不及list

                (3) 可以在兩端進(jìn)行push pop

                (4) 相對(duì)于verctor 占用更多的內(nèi)存。

            雙向隊(duì)列和向量很相似,但是它允許在容器頭部快速插入和刪除(就像在尾部一樣)。

             

            1.Constructors 創(chuàng)建一個(gè)新雙向隊(duì)列

               語法:

                  deque();//創(chuàng)建一個(gè)空雙向隊(duì)列

                  deque( size_type size );// 創(chuàng)建一個(gè)大小為size的雙向隊(duì)列

                  deque( size_type num, const TYPE &val ); //放置num個(gè)val的拷貝到隊(duì)列中

                  deque( const deque &from );// from創(chuàng)建一個(gè)內(nèi)容一樣的雙向隊(duì)列

                  deque( input_iterator start, input_iterator end );

                  // start end - 創(chuàng)建一個(gè)隊(duì)列,保存從startend的元素。

            2.Operators 比較和賦值雙向隊(duì)列

                  //可以使用[]操作符訪問雙向隊(duì)列中單個(gè)的元素

            3.assign() 設(shè)置雙向隊(duì)列的值

               語法:

                  void assign( input_iterator start, input_iterator end);

                  //startend指示的范圍為雙向隊(duì)列賦值

                  void assign( Size num, const TYPE &val );//設(shè)置成num個(gè)val

            4.at() 返回指定的元素 
               語法:

                  reference at( size_type pos ); 返回一個(gè)引用,指向雙向隊(duì)列中位置pos上的元素

            5.back() 返回最后一個(gè)元素

               語法:

                  reference back();//返回一個(gè)引用,指向雙向隊(duì)列中最后一個(gè)元素

            6.begin() 返回指向第一個(gè)元素的迭代器

               語法:

                  iterator begin();//返回一個(gè)迭代器,指向雙向隊(duì)列的第一個(gè)元素

            7.clear() 刪除所有元素

            8.empty() 返回真如果雙向隊(duì)列為空

            9.end() 返回指向尾部的迭代器

            10.erase() 刪除一個(gè)元素

               語法:

                  iterator erase( iterator pos ); //刪除pos位置上的元素

                  iterator erase( iterator start, iterator end ); //刪除startend之間的所有元素

                  //返回指向被刪除元素的后一個(gè)元素

            11.front() 返回第一個(gè)元素的引用

            12.get_allocator() 返回雙向隊(duì)列的配置器

            13.insert() 插入一個(gè)元素到雙向隊(duì)列中

               語法:

                  iterator insert( iterator pos, size_type num, const TYPE &val ); //pos前插入num個(gè)val

                  void insert( iterator pos, input_iterator start, input_iterator end );

                  //插入從startend范圍內(nèi)的元素到pos前面

            14.max_size() 返回雙向隊(duì)列能容納的最大元素個(gè)數(shù)

            15.pop_back() 刪除尾部的元素

            16.pop_front() 刪除頭部的元素

            17.push_back() 在尾部加入一個(gè)元素

            18.push_front() 在頭部加入一個(gè)元素

            19.rbegin() 返回指向尾部的逆向迭代器

            20.rend() 返回指向頭部的逆向迭代器

            21.resize() 改變雙向隊(duì)列的大小

            22.size() 返回雙向隊(duì)列中元素的個(gè)數(shù)

            23.swap() 和另一個(gè)雙向隊(duì)列交換元素

               語法:

                  void swap( deque &target );// 交換target和現(xiàn)雙向隊(duì)列中元素

            posted @ 2012-06-04 15:57 王海光 閱讀(22823) | 評(píng)論 (1)編輯 收藏
                 摘要: List(雙向鏈表)介紹:        List是一個(gè)線性鏈表結(jié)構(gòu),它的數(shù)據(jù)由若干個(gè)節(jié)點(diǎn)構(gòu)成,每一個(gè)節(jié)點(diǎn)都包括一個(gè)信息塊(即實(shí)際存儲(chǔ)的數(shù)據(jù))、一個(gè)前驅(qū)指針和一個(gè)后驅(qū)指針。它無需分配指定的內(nèi)存大小且可以任意伸縮,這是因?yàn)樗鎯?chǔ)在非連續(xù)的內(nèi)存空間中,并且由指針將有序的元素鏈接起來。    &nbs...  閱讀全文
            posted @ 2012-06-04 15:50 王海光 閱讀(4101) | 評(píng)論 (0)編輯 收藏

            C++ Vector(向量容器)

            是一個(gè)線性順序結(jié)構(gòu)。相當(dāng)于數(shù)組,但其大小可以不預(yù)先指定,并且自動(dòng)擴(kuò)展。它可以像數(shù)組一樣被操作,由于它的特性我們完全可以將vector 看作動(dòng)態(tài)數(shù)組。

            在創(chuàng)建一個(gè)vector 后,它會(huì)自動(dòng)在內(nèi)存中分配一塊連續(xù)的內(nèi)存空間進(jìn)行數(shù)據(jù)存儲(chǔ),初始的空間大小可以預(yù)先指定也可以由vector 默認(rèn)指定,這個(gè)大小即capacity ()函數(shù)的返回值。當(dāng)存儲(chǔ)的數(shù)據(jù)超過分配的空間時(shí)vector 會(huì)重新分配一塊內(nèi)存塊,但這樣的分配是很耗時(shí)的,在重新分配空間時(shí)它會(huì)做這樣的動(dòng)作:

            首先,vector 會(huì)申請(qǐng)一塊更大的內(nèi)存塊;

            然后,將原來的數(shù)據(jù)拷貝到新的內(nèi)存塊中;

            其次,銷毀掉原內(nèi)存塊中的對(duì)象(調(diào)用對(duì)象的析構(gòu)函數(shù));

            最后,將原來的內(nèi)存空間釋放掉。

            如果vector 保存的數(shù)據(jù)量很大時(shí),這樣的操作一定會(huì)導(dǎo)致糟糕的性能(這也是vector 被設(shè)計(jì)成比較容易拷貝的值類型的原因)。所以說vector 不是在什么情況下性能都好,只有在預(yù)先知道它大小的情況下vector 的性能才是最優(yōu)的。

             

            vector 的特點(diǎn):

            (1) 指定一塊如同數(shù)組一樣的連續(xù)存儲(chǔ),但空間可以動(dòng)態(tài)擴(kuò)展。即它可以像數(shù)組一樣操作,并且可以進(jìn)行動(dòng)態(tài)操作。通常體現(xiàn)在push_back() pop_back()

            (2) 隨機(jī)訪問方便,它像數(shù)組一樣被訪問,即支持[ ] 操作符和vector.at()

            (3) 節(jié)省空間,因?yàn)樗沁B續(xù)存儲(chǔ),在存儲(chǔ)數(shù)據(jù)的區(qū)域都是沒有被浪費(fèi)的,但是要明確一點(diǎn)vector 大多情況下并不是滿存的,在未存儲(chǔ)的區(qū)域?qū)嶋H是浪費(fèi)的。

            (4) 在內(nèi)部進(jìn)行插入、刪除操作效率非常低,這樣的操作基本上是被禁止的。Vector 被設(shè)計(jì)成只能在后端進(jìn)行追加和刪除操作,其原因是vector 內(nèi)部的實(shí)現(xiàn)是按照順序表的原理。

            (5) 只能在vector 的最后進(jìn)行push pop ,不能在vector 的頭進(jìn)行push pop

            (6) 當(dāng)動(dòng)態(tài)添加的數(shù)據(jù)超過vector 默認(rèn)分配的大小時(shí)要進(jìn)行內(nèi)存的重新分配、拷貝與釋放,這個(gè)操作非常消耗性能。 所以要vector 達(dá)到最優(yōu)的性能,最好在創(chuàng)建vector 時(shí)就指定其空間大小。

            Vectors 包含著一系列連續(xù)存儲(chǔ)的元素,其行為和數(shù)組類似。訪問Vector中的任意元素或從末尾添加元素都可以在常量級(jí)時(shí)間復(fù)雜度內(nèi)完成,而查找特定值的元素所處的位置或是在Vector中插入元素則是線性時(shí)間復(fù)雜度。

             

            1.Constructors 構(gòu)造函數(shù)

            vector<int> v1; //構(gòu)造一個(gè)空的vector

            vector<int> v1( 5, 42 ); //構(gòu)造了一個(gè)包含5個(gè)值為42的元素的Vector

            2.Operators 對(duì)vector進(jìn)行賦值或比較

            C++ Vectors能夠使用標(biāo)準(zhǔn)運(yùn)算符: ==, !=, <=, >=, <, 和 >.

            要訪問vector中的某特定位置的元素可以使用 [] 操作符.

            兩個(gè)vectors被認(rèn)為是相等的,如果:

            1.它們具有相同的容量

            2.所有相同位置的元素相等.

            vectors之間大小的比較是按照詞典規(guī)則.

            3.assign() 對(duì)Vector中的元素賦值

            語法:

            void assign( input_iterator start, input_iterator end );

            // 將區(qū)間[start, end)的元素賦到當(dāng)前vector

            void assign( size_type num, const TYPE &val );

            // 賦num個(gè)值為val的元素到vector中,這個(gè)函數(shù)將會(huì)清除掉為vector賦值以前的內(nèi)容。

            4.at() 返回指定位置的元素

            語法:

            TYPE at( size_type loc );//差不多等同v[i];但比v[i]安全;

            5.back() 返回最末一個(gè)元素

            6.begin() 返回第一個(gè)元素的迭代器

            7.capacity() 返回vector所能容納的元素?cái)?shù)量(在不重新分配內(nèi)存的情況下)

            8.clear() 清空所有元素

            9.empty() 判斷Vector是否為空(返回true時(shí)為空)

            10.end() 返回最末元素的迭代器(譯注:實(shí)指向最末元素的下一個(gè)位置)

            11.erase() 刪除指定元素

            語法:

            iterator erase( iterator loc );//刪除loc處的元素

            iterator erase( iterator start, iterator end );//刪除start和end之間的元素

            12.front() 返回第一個(gè)元素的引用

            13.get_allocator() 返回vector的內(nèi)存分配器

            14.insert() 插入元素到Vector中

            語法:

            iterator insert( iterator loc, const TYPE &val );

            //在指定位置loc前插入值為val的元素,返回指向這個(gè)元素的迭代器,

            void insert( iterator loc, size_type num, const TYPE &val );

            //在指定位置loc前插入num個(gè)值為val的元素

            void insert( iterator loc, input_iterator start, input_iterator end );

            //在指定位置loc前插入?yún)^(qū)間[start, end)的所有元素

            15.max_size() 返回Vector所能容納元素的最大數(shù)量(上限)

            16.pop_back() 移除最后一個(gè)元素

            17.push_back() 在Vector最后添加一個(gè)元素

            18.rbegin() 返回Vector尾部的逆迭代器

            19.rend() 返回Vector起始的逆迭代器

            20.reserve() 設(shè)置Vector最小的元素容納數(shù)量

            //為當(dāng)前vector預(yù)留至少共容納size個(gè)元素的空間

            21.resize() 改變Vector元素?cái)?shù)量的大小

            語法:

            void resize( size_type size, TYPE val );

            //改變當(dāng)前vector的大小為size,且對(duì)新創(chuàng)建的元素賦值val

            22.size() 返回Vector元素?cái)?shù)量的大小

            23.swap() 交換兩個(gè)Vector

            語法:

            void swap( vector &from );

             

             Vector用法 :

            1.聲明:

            一個(gè)vector類似于一個(gè)動(dòng)態(tài)的一維數(shù)組。

            vector<int> a; //聲明一個(gè)元素為int類型的vector a

            vectot<MyType> a; //聲明一個(gè)元素為MyType類型的vector a

            這里的聲明的a包含0個(gè)元素,既a.size()的值為0,但它是動(dòng)態(tài)的,其大小會(huì)隨著數(shù)據(jù)的插入和刪除改變而改變。

            vector<int> a(100, 0); //這里聲明的是一個(gè)已經(jīng)存放了100個(gè)0的整數(shù)vector

            你可以用以下的幾種方法聲明一個(gè) vector 對(duì)象:

            vector<float> v(5, 3.25); //初始化有5 個(gè)元素,其值都是3.25

            vector<float> v_new1(v);

            vector<float> v_new2 = v;

            vector<float> v_new3(v.begin(), v.end());

            這四個(gè)vector 對(duì)象是相等的,可以用operator==來判斷。

            2.向量操作

            常用函數(shù):

            size_t size(); // 返回vector的大小,即包含的元素個(gè)數(shù)

            void pop_back(); // 刪除vector末尾的元素,vector大小相應(yīng)減一

            void push_back(); //用于在vector的末尾添加元素

            T back(); // 返回vector末尾的元素

            void clear(); // 將vector清空,vector大小變?yōu)?

            其他訪問方式:

            cout<<a[5]<<endl;

            cout<<a.at(5)<<endl;

            以上區(qū)別在于后者在訪問越界時(shí)會(huì)拋出異常,而前者不會(huì)。

            3.遍歷

            (1). for(vector<datatype>::iterator it=a.begin(); it!=a.end();it++)

            cout<<*it<<endl;

            (2). for(int i=0;i<a.size;i++)

            cout<<a[i]<<endl;

             

            現(xiàn)在想得到容器中能保存的最大元素?cái)?shù)量就可以用 vector 類的成員函數(shù)max_size():

            vector<shape>::size_type max_size = my_shapes.max_size();

            當(dāng)前容器的實(shí)際尺寸 --- 已有的元素個(gè)數(shù)用size():

            vector<shape>::size_type size = my_shapes.size();

            就像size_type 描述了vector 尺寸的類型,value_type 說明了其中保存的對(duì)象的類型:

            cout << “value type: “ << typeid(vector<float>::value_type).name();

            輸出:

            value type: float

            可以用capacity()來取得vector 中已分配內(nèi)存的元素個(gè)數(shù):

            vector<int> v;

            vector<int>::size_type capacity = v.capacity();

            vector 類似于數(shù)組,可以使用下標(biāo)[]訪問:

            vector<int> v(10);

            v[0] = 101;

            注意到這里預(yù)先給10 個(gè)元素分配了空間。你也可以使用vector 提供的插入函數(shù)來動(dòng)態(tài)的擴(kuò)

            展容器。成員函數(shù)push_back()就在vector 的尾部添加了一個(gè)元素:

            v.push_back(3);

            也可以用insert()函數(shù)完成同樣的工作:

            v.insert(v.end(), 3);

            這里insert()成員函數(shù)需要兩個(gè)參數(shù):一個(gè)指向容器中指定位置的迭代器(iterator),一個(gè)待插

            入的元素。insert()將元素插入到迭代器指定元素之前。

            現(xiàn)在對(duì)迭代器(Iterator)做點(diǎn)解釋。Iterator 是指針(pointer)的泛化,iterator 要求定義

            operator*,它返回指定類型的值。Iterator 常常和容器聯(lián)系在一起。例子:

            vector<int> v(3);

            v[0] = 5;

            v[1] = 2;

            v[2] = 7;

             

            vector<int>::iterator first = v.begin();

            vector<int>::iterator last = v.end();

            while (first != last)

            cout << *first++ << “ “;

            上面代碼的輸出是:

            5 2 7

            begin()返回的是vector 中第一個(gè)元素的iterator,而end()返回的并不是最后一個(gè)元素的

            iterator,而是past the last element。在STL 中叫past-the-end iterator

            組合查找
            vector<int>::iterator result = find( v.begin( ), v.end( ), 2 ); //查找2
            if ( result == v.end( ) ) //沒找到
                    cout << "No" << endl;
             else //找到
                    cout << "Yes" << endl;


             

            posted @ 2012-06-04 09:18 王海光 閱讀(11039) | 評(píng)論 (0)編輯 收藏

            STL介紹
                C++ STL (Standard Template Library
            標(biāo)準(zhǔn)模板庫) 是通用類模板和算法的集合,它提供給程序員一些標(biāo)準(zhǔn)的數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)如 queues(隊(duì)列), lists(鏈表), stacks(). 該庫包含了諸多在計(jì)算機(jī)科學(xué)領(lǐng)域里所常用的基本數(shù)據(jù)結(jié)構(gòu)和基本算法。提供了一個(gè)可擴(kuò)展的應(yīng)用框架,高度體現(xiàn)了軟件的可復(fù)用性。
            從邏輯層次來看,在STL中體現(xiàn)了泛型化程序設(shè)計(jì)的思想(generic programming),引入了諸多新的名詞,比如像需求(requirements),概念(concept),模型(model),容器(container),算法(algorithmn),迭代子(iterator)等。與OOP(object-oriented programming)中的多態(tài)(polymorphism)一樣,泛型也是一種軟件的復(fù)用技術(shù)。
            從實(shí)現(xiàn)層次看,整個(gè)STL是以一種類型參數(shù)化(type parameterized)的方式實(shí)現(xiàn)的,這種方式基于一個(gè)在早先C++標(biāo)準(zhǔn)中沒有出現(xiàn)的語言特性--模板(template)。
            C++ STL 提供給程序員以下三類數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)
            標(biāo)準(zhǔn)容器類
             
            順序性容器
               vector 從后面快速的插入與刪除,直接訪問任何元素
               deque 從前面或后面快速的插入與刪除,直接訪問任何元素
               list 雙鏈表,從任何地方快速插入與刪除
             
            三者比較:
               vector 是一段連續(xù)的內(nèi)存塊,而deque 是多個(gè)連續(xù)的內(nèi)存塊, list 是所有數(shù)據(jù)元素分開保存,可以是任何兩個(gè)元素沒有連續(xù)。vector 的查詢性能最好,并且在末端增加數(shù)據(jù)也很好,除非它重新申請(qǐng)內(nèi)存段;適合高效地隨機(jī)存儲(chǔ)。list 是一個(gè)鏈表,任何一個(gè)元素都可以是不連續(xù)的,但它都有兩個(gè)指向上一元素和下一元素的指針。所以它對(duì)插入、刪除元素性能是最好的,而查詢性能非常差;適合大量地插入和刪除操作而不關(guān)心隨機(jī)存取的需求。deque 是介于兩者之間,它兼顧了數(shù)組和鏈表的優(yōu)點(diǎn),它是分塊的鏈表和多個(gè)數(shù)組的聯(lián)合。所以它有被list好的查詢性能,有被vector好的插入、刪除性能。 如果你需要隨即存取又關(guān)心兩端數(shù)據(jù)的插入和刪除,那么deque是最佳之選。

            關(guān)聯(lián)容器
               set 快速查找,不允許重復(fù)值
               multiset 快速查找,允許重復(fù)值
               map 一對(duì)多映射,基于關(guān)鍵字快速查找,不允許重復(fù)值
               multimap 一對(duì)多映射,基于關(guān)鍵字快速查找,允許重復(fù)值

               關(guān)聯(lián)容器(Associative Container)提供了快速檢索基于關(guān)鍵詞(Key)的數(shù)據(jù)的能力。和序列容器(vector、list、deque)一樣,關(guān)聯(lián)容器用來存儲(chǔ)數(shù)據(jù),而且設(shè)計(jì)關(guān)聯(lián)容器時(shí)考慮到了優(yōu)化數(shù)據(jù)檢索的意圖 --- 通過關(guān)鍵詞(Key)作為標(biāo)識(shí)把單一的數(shù)據(jù)記錄組織到特定的結(jié)構(gòu)中(如tree)。STL 提供了不同的關(guān)聯(lián)容器:集合(set)、多元集合(multiset)、映射(map)、多元映射(multimap)。set 和map 支持唯一關(guān)鍵詞(unique key),就是對(duì)每個(gè)KEY,最多只保存一個(gè)元素(數(shù)據(jù)
            記錄)。multiset 和multimap 則支持相同關(guān)鍵詞(equal key),這樣可有很多個(gè)元素可以用同一個(gè)KEY 進(jìn)行存儲(chǔ)。set(multiset)和map(multimap)之間的區(qū)別在于set(multiset)中的存儲(chǔ)數(shù)據(jù)內(nèi)含了KEY 表達(dá)式;而map(multimap)則將Key 表達(dá)式和對(duì)應(yīng)的數(shù)據(jù)分開存放。

            容器適配器
               stack 后進(jìn)先出
               queue 先進(jìn)先出
               priority_queue 最高優(yōu)先級(jí)元素總是第一個(gè)出列

               STL 中包含三種適配器:棧stack 、隊(duì)列queue 和優(yōu)先級(jí)priority_queue 。適配器是容器的接口,它本身不能直接保存元素,它保存元素的機(jī)制是調(diào)用另一種順序容器去實(shí)現(xiàn),即可以把適配器看作“它保存一個(gè)容器,這個(gè)容器再保存所有元素”。
               STL 中提供的三種適配器可以由某一種順序容器去實(shí)現(xiàn)。默認(rèn)下stack 和queue 基于deque 容器實(shí)現(xiàn),priority_queue 則基于vector 容器實(shí)現(xiàn)。當(dāng)然在創(chuàng)建一個(gè)適配器時(shí)也可以指定具體的實(shí)現(xiàn)容器,創(chuàng)建適配器時(shí)在第二個(gè)參數(shù)上指定具體的順序容器可以覆蓋適配器的默認(rèn)實(shí)現(xiàn)。由于適配器的特點(diǎn),一個(gè)適配器不是可以由任一個(gè)順序容器都可以實(shí)現(xiàn)的。
               棧stack 的特點(diǎn)是后進(jìn)先出,所以它關(guān)聯(lián)的基本容器可以是任意一種順序容器,因?yàn)檫@些容器類型結(jié)構(gòu)都可以提供棧的操作有求,它們都提供了push_back 、pop_back 和back 操作。
               隊(duì)列queue 的特點(diǎn)是先進(jìn)先出,適配器要求其關(guān)聯(lián)的基礎(chǔ)容器必須提供pop_front 操作,因此其不能建立在vector 容器上。
            posted @ 2012-06-04 08:52 王海光 閱讀(914) | 評(píng)論 (0)編輯 收藏
                 摘要: 本文轉(zhuǎn)自:http://www.cnblogs.com/zqrferrari/archive/2010/07/07/1773113.html 一、MFC對(duì)多線程編程的支持   MFC中有兩類線程,分別稱之為工作者線程和用戶界面線程。二者的主要區(qū)別在于工作者線程沒有消息循環(huán),而用戶界面線程有自己的消息隊(duì)列和消息循環(huán)。  工作者線程沒有消息機(jī)制,通常用來執(zhí)行后臺(tái)計(jì)算和維護(hù)任務(wù),如冗長的計(jì)算過程...  閱讀全文
            posted @ 2012-05-31 14:34 王海光 閱讀(3065) | 評(píng)論 (1)編輯 收藏
            本文轉(zhuǎn)自:http://www.cnblogs.com/jillzhang/archive/2006/11/02/547679.html

            哈希表和哈希函數(shù)是大學(xué)數(shù)據(jù)結(jié)構(gòu)中的課程,實(shí)際開發(fā)中我們經(jīng)常用到Hashtable這種結(jié)構(gòu),當(dāng)遇到鍵-值對(duì)存儲(chǔ),采用Hashtable比ArrayList查找的性能高。為什么呢?我們?cè)谙硎芨咝阅艿耐瑫r(shí),需要付出什么代價(jià)(這幾天看紅頂商人胡雪巖,經(jīng)典臺(tái)詞:在你享受這之前,必須受別人吃不了的苦,忍受別人受不了的屈辱),那么使用Hashtable是否就是一樁無本萬利的買賣呢?就此疑問,做以下分析,希望能拋磚引玉。
            1)hash它為什么對(duì)于鍵-值查找性能高
            學(xué)過數(shù)據(jù)結(jié)構(gòu)的,都應(yīng)該曉得,線性表和樹中,記錄在結(jié)構(gòu)中的相對(duì)位置是隨機(jī)的,記錄和關(guān)鍵字之間不存在明確的關(guān)系,因此在查找記錄的時(shí)候,需要進(jìn)行一系列的關(guān)鍵字比較,這種查找方式建立在比較的基礎(chǔ)之上,在.net中(Array,ArrayList,List)這些集合結(jié)構(gòu)采用了上面的存儲(chǔ)方式。
            比如,現(xiàn)在我們有一個(gè)班同學(xué)的數(shù)據(jù),包括姓名,性別,年齡,學(xué)號(hào)等。假如數(shù)據(jù)有

            姓名 性別 年齡 學(xué)號(hào)
            張三 15 1
            李四 14 2
            王五 14 3

             

            假如,我們按照姓名來查找,假設(shè)查找函數(shù)FindByName(string name);
            1)查找“張三”
            只需在第一行匹配一次。
            2)查找"王五"
               在第一行匹配,失敗,
               在第二行匹配,失敗,
               在第三行匹配,成功
            上面兩種情況,分別分析了最好的情況,和最壞的情況,那么平均查找次數(shù)應(yīng)該為 (1+3)/2=2次,即平均查找次數(shù)為(記錄總數(shù)+1)的1/2。
            盡管有一些優(yōu)化的算法,可以使查找排序效率增高,但是復(fù)雜度會(huì)保持在log2n的范圍之內(nèi)。
            如何更更快的進(jìn)行查找呢?我們所期望的效果是一下子就定位到要找記錄的位置之上,這時(shí)候時(shí)間復(fù)雜度為1,查找最快。如果我們事先為每條記錄編一個(gè)序號(hào),然后讓他們按號(hào)入位,我們又知道按照什么規(guī)則對(duì)這些記錄進(jìn)行編號(hào)的話,如果我們?cè)俅尾檎夷硞€(gè)記錄的時(shí)候,只需要先通過規(guī)則計(jì)算出該記錄的編號(hào),然后根據(jù)編號(hào),在記錄的線性隊(duì)列中,就可以輕易的找到記錄了 。
            注意,上述的描述包含了兩個(gè)概念,一個(gè)是用于對(duì)學(xué)生進(jìn)行編號(hào)的規(guī)則,在數(shù)據(jù)結(jié)構(gòu)中,稱之為哈希函數(shù),另外一個(gè)是按照規(guī)則為學(xué)生排列的順序結(jié)構(gòu),稱之為哈希表。
            仍以上面的學(xué)生為例,假設(shè)學(xué)號(hào)就是規(guī)則,老師手上有一個(gè)規(guī)則表,在排座位的時(shí)候也按照這個(gè)規(guī)則來排序,查找李四,首先該教師會(huì)根據(jù)規(guī)則判斷出,李四的編號(hào)為2,就是在座位中的2號(hào)位置,直接走過去,“李四,哈哈,你小子,就是在這!”
            看看大體流程:
             
            從上面的圖中,可以看出哈希表可以描述為兩個(gè)筒子,一個(gè)筒子用來裝記錄的位置編號(hào),另外一個(gè)筒子用來裝記錄,另外存在一套規(guī)則,用來表述記錄與編號(hào)之間的聯(lián)系。這個(gè)規(guī)則通常是如何制定的呢?
            a)直接定址法:
               我在前一篇文章對(duì)GetHashCode()性能比較的問題中談到,對(duì)于整形的數(shù)據(jù)GetHashCode()函數(shù)返回的就是整形   本身,其實(shí)就是基于直接定址的方法,比如有一組0-100的數(shù)據(jù),用來表示人的年齡
            那么,采用直接定址的方法構(gòu)成的哈希表為:

            0 1 2 3 4 5
            0歲 1歲 2歲 3歲 4歲 5歲
            .....
            這樣的一種定址方式,簡單方便,適用于元數(shù)據(jù)能夠用數(shù)字表述或者原數(shù)據(jù)具有鮮明順序關(guān)系的情形。
            b)數(shù)字分析法:
              有這樣一組數(shù)據(jù),用于表述一些人的出生日期
            75 10
            75 12 10
            75 02 14
            分析一下,年和月的第一位數(shù)字基本相同,造成沖突的幾率非常大,而后面三位差別比較大,所以采用后三位
            c)平方取中法
             取關(guān)鍵字平方后的中間幾位作為哈希地址
            d) 折疊法:
             將關(guān)鍵字分割成位數(shù)相同的幾部分,最后一部分位數(shù)可以不相同,然后去這幾部分的疊加和(取出進(jìn)位)作為哈希地址,比如有這樣的數(shù)據(jù)20-1445-4547-3
            可以
                    5473
            +      4454
            +        201
            =    10128
            取出進(jìn)位1,取0128為哈希地址
            e)取余法
            取關(guān)鍵字被某個(gè)不大于哈希表表長m的數(shù)p除后所得余數(shù)為哈希地址。H(key)=key MOD p (p<=m)
            f) 隨機(jī)數(shù)法
             選擇一個(gè)隨機(jī)函數(shù),取關(guān)鍵字的隨機(jī)函數(shù)值為它的哈希地址,即H(key)=random(key) ,其中random為隨機(jī)函數(shù)。通常用于關(guān)鍵字長度不等時(shí)采用此法。

             

            總之,哈希函數(shù)的規(guī)則是:通過某種轉(zhuǎn)換關(guān)系,使關(guān)鍵字適度的分散到指定大小的的順序結(jié)構(gòu)中。越分散,則以后查找的時(shí)間復(fù)雜度越小,空間復(fù)雜度越高。
            2)使用hash,我們付出了什么?
            hash是一種典型以空間換時(shí)間的算法,比如原來一個(gè)長度為100的數(shù)組,對(duì)其查找,只需要遍歷且匹配相應(yīng)記錄即可,從空間復(fù)雜度上來看,假如數(shù)組存儲(chǔ)的是byte類型數(shù)據(jù),那么該數(shù)組占用100byte空間。現(xiàn)在我們采用hash算法,我們前面說的hash必須有一個(gè)規(guī)則,約束鍵與存儲(chǔ)位置的關(guān)系,那么就需要一個(gè)固定長度的hash表,此時(shí),仍然是100byte的數(shù)組,假設(shè)我們需要的100byte用來記錄鍵與位置的關(guān)系,那么總的空間為200byte,而且用于記錄規(guī)則的表大小會(huì)根據(jù)規(guī)則,大小可能是不定的,比如在lzw算法中,如果一個(gè)很長的用于記錄像素的byte數(shù)組,用來記錄位置與鍵關(guān)系的表空間,算法推薦為一個(gè)12bit能表述的整數(shù)大小,那么足夠長的像素?cái)?shù)組,如何分散到這樣定長的表中呢,lzw算法采用的是可變長編碼,具體會(huì)在深入介紹lzw算法的時(shí)候介紹。
            注:hash表最突出的問題在于沖突,就是兩個(gè)鍵值經(jīng)過哈希函數(shù)計(jì)算出來的索引位置很可能相同,這個(gè)問題,下篇文章會(huì)令作闡述。
            注:之所以會(huì)簡單得介紹了hash,是為了更好的學(xué)習(xí)lzw算法,學(xué)習(xí)lzw算法是為了更好的研究gif文件結(jié)構(gòu),最后,我將詳細(xì)的闡述一下gif文件是如何構(gòu)成的,如何高效操作此種類型文件。

            HASH如何處理沖突

            1)沖突是如何產(chǎn)生的?
            上文中談到,哈希函數(shù)是指如何對(duì)關(guān)鍵字進(jìn)行編址的規(guī)則,這里的關(guān)鍵字的范圍很廣,可視為無限集,如何保證無限集的原數(shù)據(jù)在編址的時(shí)候不會(huì)出現(xiàn)重復(fù)呢?規(guī)則本身無法實(shí)現(xiàn)這個(gè)目的。舉一個(gè)例子,仍然用班級(jí)同學(xué)做比喻,現(xiàn)有如下同學(xué)數(shù)據(jù)
            張三,李四,王五,趙剛,吳露.....
            假如我們編址規(guī)則為取姓氏中姓的開頭字母在字母表的相對(duì)位置作為地址,則會(huì)產(chǎn)生如下的哈希表
            位置 字母 姓名
            0 a
            1 b
            2 c

             

            ...
            10    L     李四

            ...
            22 W 王五,吳露
            ..
            25  張三,趙剛

            我們注意到,灰色背景標(biāo)示的兩行里面,關(guān)鍵字王五,吳露被編到了同一個(gè)位置,關(guān)鍵字張三,趙剛也被編到了同一個(gè)位置。老師再拿號(hào)來找張三,座位上有兩個(gè)人,"你們倆誰是張三?"
            2)如何解決沖突問題
            既然不能避免沖突,那么如何解決沖突呢,顯然需要附加的步驟。通過這些步驟,以制定更多的規(guī)則來管理關(guān)鍵字集合,通常的辦法有:
            a)開放地址法
            開放地執(zhí)法有一個(gè)公式:Hi=(H(key)+di) MOD m i=1,2,...,k(k<=m-1)
            其中,m為哈希表的表長。di 是產(chǎn)生沖突的時(shí)候的增量序列。如果di值可能為1,2,3,...m-1,稱線性探測再散列。
            如果di取1,則每次沖突之后,向后移動(dòng)1個(gè)位置.如果di取值可能為1,-1,2,-2,4,-4,9,-9,16,-16,...k*k,-k*k(k<=m/2) 
            稱二次探測再散列。如果di取值可能為偽隨機(jī)數(shù)列。稱偽隨機(jī)探測再散列。仍然以學(xué)生排號(hào)作為例子,
            現(xiàn)有兩名同學(xué),李四,吳用。李四與吳用事先已排好序,現(xiàn)新來一名同學(xué),名字叫王五,對(duì)它進(jìn)行編制
            10.. .... 22 .. .. 25
            李四.. .... 吳用 .. .. 25
               趙剛未來之前
            10.. .. 22 23 25
            李四.. 吳用 王五
               (a)線性探測再散列對(duì)趙剛進(jìn)行編址,且di=1
            10... 20 22 .. 25
            李四.. 王五 吳用
               (b)二次探測再散列,且di=-2
            1... 10... 22 .. 25
            王五.. 李四.. 吳用
               (c)偽隨機(jī)探測再散列,偽隨機(jī)序列為:5,3,2

            b)再哈希法 
            當(dāng)發(fā)生沖突時(shí),使用第二個(gè)、第三個(gè)、哈希函數(shù)計(jì)算地址,直到無沖突時(shí)。缺點(diǎn):計(jì)算時(shí)間增加。
            比如上面第一次按照姓首字母進(jìn)行哈希,如果產(chǎn)生沖突可以按照姓字母首字母第二位進(jìn)行哈希,再?zèng)_突,第三位,直到不沖突為止
            c)鏈地址法
            將所有關(guān)鍵字為同義詞的記錄存儲(chǔ)在同一線性鏈表中。如下:

            因此這種方法,可以近似的認(rèn)為是筒子里面套筒子
            d.建立一個(gè)公共溢出區(qū)
            假設(shè)哈希函數(shù)的值域?yàn)閇0,m-1],則設(shè)向量HashTable[0..m-1]為基本表,另外設(shè)立存儲(chǔ)空間向量OverTable[0..v]用以存儲(chǔ)發(fā)生沖突的記錄。
            經(jīng)過以上方法,基本可以解決掉hash算法沖突的問題。

            posted @ 2012-05-28 15:54 王海光 閱讀(1333) | 評(píng)論 (0)編輯 收藏
            僅列出標(biāo)題
            共27頁: First 18 19 20 21 22 23 24 25 26 Last 
            久久精品无码一区二区三区免费| 久久99免费视频| 伊人久久大香线蕉综合Av| 久久国产色av免费看| 午夜欧美精品久久久久久久| 狠狠色丁香久久综合婷婷| 国产精品内射久久久久欢欢| 久久久久九九精品影院| 久久精品一区二区三区AV| 久久免费的精品国产V∧| 久久91综合国产91久久精品| 久久久人妻精品无码一区| 久久久久久久久波多野高潮| 国产一久久香蕉国产线看观看| 久久久亚洲精品蜜桃臀| 久久久无码精品亚洲日韩按摩| 久久精品国产亚洲一区二区| 色老头网站久久网| 久久精品国产亚洲av水果派| 久久久久国产一区二区三区| 97精品伊人久久久大香线蕉| 91精品国产综合久久四虎久久无码一级| 日韩久久久久中文字幕人妻 | 久久久久人妻一区二区三区| 91视频国产91久久久| 亚洲国产成人精品女人久久久| 精品久久人妻av中文字幕| 午夜精品久久久久久影视777| 精品久久久久久久无码| 亚洲国产精品一区二区三区久久| 国产精品久久久久久久久| 久久精品国产亚洲av麻豆蜜芽| 成人国内精品久久久久影院VR| 亚洲国产另类久久久精品黑人 | 72种姿势欧美久久久久大黄蕉| 人人狠狠综合久久亚洲高清| 青青青伊人色综合久久| 久久午夜羞羞影院免费观看| 色狠狠久久综合网| 怡红院日本一道日本久久| 久久国产精品成人影院|