有序的迴圈鏈表中插入結點

來源:互聯網
上載者:User
題目

給定一個有序的迴圈鏈表,在其中插入一個值,保持該迴圈鏈表依然有序。

分析

首先看下迴圈鏈表的結構,如所示為一個迴圈鏈表,其尾結點指向頭結點,從而形成一個迴圈。給定的鏈表結點可以是鏈表任意一個結點,這個結點不一定是鏈表頭結點,從而這也增加了該題的難度。

此時若是要在鏈表中插入4,則插入後的鏈表如下所示:

可以看到插入4後,鏈表依然有序。

在解決這個問題前,先來看一個簡化的問題,就是在一個有序單鏈表中插入結點,仍然保證其有序。這個問題的代碼相信多數人都很熟悉,一般都是分兩種情況考慮:

1)如果原來鏈表為空白或者插入的結點值最小,則直接插入該結點並設定為頭結點。

2)如果原來鏈表非空,則找到第一個大於該結點值的結點,並插入到該結點的前面。如果插入的結點值最大,則插入在尾部。

代碼如下:

//鏈表結點定義struct node {  int data;  struct node *next;};typedef struct node Node;

void sortedInsert3(struct node** headRef, struct node* nd){    if (*headRef==NULL || (*headRef)->data>=nd->data) { //情況1        nd->next = *headRef;        *headRef = nd;    } else {  //情況2        struct node* current = *headRef;        while (current->next != NULL && current->next->data < nd->data)            current = current->next;        nd->next = current->next;        current->next = nd;    }}

當然也可以把情況1和情況2放到一起考慮,代碼會更簡潔,如下所示:

void sortedInsert2(struct node** headRef, struct node* nd){    struct node** current = headRef;    while ( (*current)!=NULL && ((*current)->data<nd->data) ) {        current = &((*current)->next);    }    nd->next = *current;    *current = nd;}

上面代碼很簡潔,注意它是怎麼處理特殊情況的。

1)當鏈表為空白或者插入的結點值最小時,則直接跳出迴圈,設定nd->next=NULL, *headRef=nd.

2)其他情況,則current為待插入結點的位置,直接將其插入即可。包括插入到尾部或者任意常規的位置。

解決方案

解決了一個輕量級的問題之後再來看原題,該題目與上面不同的地方在於它是一個迴圈鏈表,那麼情況會有所不同,設待插入的結點值為x,則至少需要考慮下面三種情況

1.prev->val ≤ x ≤ current->val:

     插入到prev和current之間。

2. x是鏈表中最小或者最大的值:

      插入x到鏈表頭部的前面。

3.回到起始點:
     插入到起始點前面。

第1和2種情況還比較容易考慮到,但是第3種情況往往會被忽略,先給出代碼,再根據代碼來分析這些情況為什麼都需要考慮到。

void insert(Node *& aNode, int x) {  //鏈表為空白,建立節點返回  if (!aNode) {    aNode = new Node(x);    aNode->next = aNode;    return;  }   Node *p = aNode;  Node *prev = NULL;  do {    prev = p;    p = p->next;    if (x <= p->data && x >= prev->data) break;   // 情況1,找到正常位置返回,如例子中插入4到鏈表中    if ((prev->data > p->data) && (x < p->data || x > prev->data)) break; // 情況2,x最小或者最大,插入到鏈表最前面  } while (p != aNode);   // 情況3,回到起始結點,停止.    Node *newNode = newNode(x);  newNode->next = p;  prev->next = newNode;}

1)鏈表只有一個結點

     如果x等於該結點值,則直接在情況1處理。否則情況3處理。

2)鏈表包含重複值

    如果鏈表為1-*1-1,起始結點為第二個1,則在其中插入2時,由情況3處理,即最終插入到初始結點前面。會變成1-2-1-1.迴圈鏈表從第二個1開始,照樣是有序的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.