1. 程式人生 > >[轉載]Qlist的用法

[轉載]Qlist的用法

QList是一種表示連結串列的模板類。

QList是Qt的一種泛型容器類。它以連結串列方式儲存一組值,並能對這組資料進行快速索引,還提供了快速插入和刪除等操作。

QList、QLinkedList和QVector提供的操作極其相似:

* 對大多數操作來說,我們用QList就可以了。其API是基於索引(index)的,因此用起來比QLinkedList更方便(QLinkedList的API是基於迭代器的)。QList比QVector更快,這是由它們在記憶體中的儲存方式決定的。

* 需要使用QLinkedList的地方:

* 需要使用QVector的地方:元素的儲存位置彼此相鄰。

 

QList表示為一組指向被儲存元素的陣列。(例外,如果T本身就是指標型別,或者是size不大於指標型別的基本型別,或者是Qt的共享類,那麼QList會直接在指標陣列中儲存這些元素。)元素個數小於1000的QList能夠很快地實現在連結串列中間插入操作,以及快速的查詢操作。此外,由於QList在連結串列兩端都預先分配了記憶體,因此實現prepend()和append()操作都很快。

注意:對於size比指標大的共享類,使用QVector會更好。

 

以下是兩個分別儲存int型資料和QDate型別資料的連結串列:

QList intList;

QList dateList;

對於字串連結串列,Qt提供了QStringList類。它繼承自QList,但還提供了一些其他便於使用字串的函式:QStringList::join()、QStringList::find()、QStringList::split()。

 

QList以連結串列形式儲存一組元素。預設為空連結串列,我們可以使用<<操作符新增元素:

QList list;

list << "one" << "two" << "three"; // list: ["one", "two", "three"]

QList提供了一系列新增、移動、刪除元素的操作:insert(), replace(), removeAt(), swap()

。此外,它還提供了便於操作的函式:append(), prepend(), removeFirst(), removeLast()。

QList與C++中陣列的索引方式一樣,都是從0開始的。我們可以使用[]操作符來訪問位於索引值處的元素。對於非const連結串列,操作符[]返回的是該元素的引用,並且返回值可以用途左運算元。

if ( list[0] == "Bob" )

   list[0] = "Robert";

由於QList是以指標陣列的形式實現的,該操作能夠很快地實現(時間複雜度為常數)。對於只讀訪問,我們可以用at()函式實現訪問:

for ( int i=0; i!=list.size(); ++i )

{

   if ( list.at(i) == "Jane" )

   { cout << "Found Jane at position:" << i<< endl;}

}

at()操作比操作符[]更快,因為它不需要深度複製(deep copy)。

QList的一個常用操作是,從連結串列中取出一個元素(元素不再在連結串列之中),並對該元素進行操作。

QList提供了以下操作來實現此功能:takeAt()、takeFirst()、takeLast()。以下是一個示例:

QList list;

...

while ( !list.isEmpty() )

   deleta list.takeFirst();

由於QList在連結串列兩端都預先分配了快取以應對連結串列兩端的快速新增操作,這樣就使得在QList的

兩端插入或刪除元素變得非常地快。

如果需要找出某個值在連結串列中出現的位置,我們可以使用indexOf()、lastIndexOf()函式來實現。

前者進行前向查詢,而後者則進行反向查詢。兩者都會在找到匹配元素後返回該元素的索引值。若

沒有找到匹配元素,則返回-1。例如:

int i = indexOf("Jane");

if ( i!=-1 )

   cout << "First occurance of Jane is at position" << i << endl;

 

如果僅僅是想判斷連結串列中是否包含某一值,我們可以使用函式contains()。如果希望知道某一值在

連結串列中的出現次數,使用count()函式。如果要替換掉連結串列中所有值與某一值相同的元素,使用

replace()。

 

QList的值必須是可數的型別。這包含了我們常用的大多數型別。但是,如果我們儲存QWidget型別

的話,編譯器也不會通知我們出錯了。但是,我們應該使用QWidget *,而不是QWidget。此外,一

些函式還作出了其它限制,比如:indexOf()和lastIndexOf()操作要求值的型別能進行“==”操作。

 

與其他容器一樣,QList也提供了Java形式的迭代器(QListIterator和QMutableListIterator)。

以及STL形式的迭代器(QList::const_iterator和QList::iterator)。實際上,由於可通過索引值

來訪問元素,我們很少使用這些迭代器。使用索引值訪問元素的速度與迭代器相差無幾。

 

為了提高效率,QList的成員函式在使用前並不會驗證其引數是否有效。除isEmpty()函式外,其它

成員函式都會假定該容器為非空容器;使用索引值(index)進行操作的成員函式都會假定其索引值參

數是在有效範圍內的。這就意味著,QList在有些時候會出錯。如果在編譯時,我們定義了QT_NO_DEBUG

,編譯過程中就不會檢測這些錯誤。如果沒有定義QT_NO_DEBUG,我們可以利用Q_ASSERT()或者

Q_ASSERT_X()加上一些合理的資訊來實現錯誤檢測。

 

我們可以在呼叫其他函式之前先呼叫isEmpty()函式判斷連結串列是否為空,以避免對空連結串列進行錯

誤操作。而對於以索引值index為引數的成員函式,我們還需要判斷該索引值是否位於有效範圍

內。 

 

 

 

 

 

QList list;

 

   list<<1<<2<<3<<4<<5<<6<<7<<8;

 

 

 

QList的插入

 

    void append(const T&value)            在QList尾部插入value

 

    void append(const TQList&value)       在QList尾部插入QList&value

 

    void insert ( int i, const T & value )      在QList其中某個位置插入value,假如沒 宣告i ,i 預設size()及在最後插入value

 

    iterator insert ( iterator before, const T & value )    在迭代器的前個位置插入value並返回當前迭代器的位置

 

 

 

QList的刪除

 

     void clear ()   刪除QList的內容

 

     iterator erase ( iterator pos )     刪除迭代器位置的值,返回下個迭代器位置

 

     iterator erase ( iterator begin, iterator end )  刪除一塊的迭代器begin和end的值,返回下一個迭代器

 

            QList::iterator i;

 

            i=list.begin();

 

            i++;

 

            i=list.erase(i,i+2);

 

             for(i=list.begin();i!=list.end();i++)

 

            {

 

                qDebug()<<(*i);

 

            }

 

  

 

      int removeAll ( const T & value )    刪除返回刪除個數    

 

 QList list;

 list << "sun" << "cloud" << "sun" << "rain";

 list.removeAll("sun");

 // list: ["cloud", "rain"]

 

      void removeAt ( int i )      刪除某個值

 

      void removeFirst ()        刪除最前一個值

 

      void removeLast ()         刪除最後一個值

 

      bool removeOne ( const T & value )     刪除value中的一個

 

 

 

 QList list;

 list << "sun" << "cloud" << "sun" << "rain";

 list.removeOne("sun");

 // list: ["cl