數據結構之循環鏈表05

鞏固題目:
1.判斷給定的鏈表中是否是循環鏈表
2.鏈表是否存在環的判斷
3.鏈表中環入口的查找,同樣使用快慢指針
4.查找一個非循環鏈表中的中間節點的值
5.雙向鏈表的建立
6.雙向鏈表插入
=======================================================
2013.08.12
課題:循環鏈表
=======================================================

與單向鏈表區別:尾指針指針域並不指向NULL,而是指向頭節點

單向循環鏈表的操作與非循環相似,唯一區別在於,函數中鏈表結束判斷不再是判 
斷指針域是否是NULL,而是判斷它是否等於頭指針。

=======================================================
2013.08.12
課題:循環鏈表
=======================================================

與單向鏈表區別:尾指針指針域並不指向NULL,而是指向頭節點

單向循環鏈表的操作與非循環相似,唯一區別在於,函數中鏈表結束判斷不再是判 
斷指針域是否是NULL,而是判斷它是否等於頭指針。

1.判斷給定的鏈表中是否是循環鏈表
--------------------------------
typedef struct node_t {
     int data;
     struct node_t *next;
}NODE_T;

使用一個指針不斷步進,當該指針等於NULL則說明不是循環鏈表
如果某次該指針等於頭結點,則說明是循環鏈表
----------------------------------------------------------
int is_looplist(NODE_T *head)
{
     NODE_T *list;

     if (!head)
         return -1;

     list = head->next;

     while(list && list != head) {
         list = list->next;
     }

     if (!list)
         return -1;

     else /* exsit backloop */
         return 1;
}

2.鏈表是否存在環,使用網上流傳的快慢指針,慢指針步長爲1,慢指針步長爲2
因此,快指針肯定比慢指針先進入環(並死循環在環裏),當慢指針進入環後,總會 
和快指針相等,此時可以判斷該鏈表存在環
------------------------------------
int is_looplist(NODE_T *list)
{
     NODE_T *fast, *slow;


     if (!list)
         return -1;

     fast = list;
     slow = list;

     while (slow && fast && fast->next) {
         slow = slow->next;
         fast = fast->next->next;
         if (fast == slow)
             return 1;
     }

     return 0;
}

3.鏈表中環入口的查找,同樣使用快慢指針
慢指針步長爲1,快指針爲2
---------------------------------------
假設,環入口的距離爲L,慢指針在環內走的距離爲l,
L+l = N , N爲慢指針走的總步長,此時快指針的總步長爲2N, 慢指針再步進N步 
還是會到達該點(N + N = 2N)
此時,如果讓另外一個指針指向頭節點,然後以步長爲1的長度走N步,也會到達慢 
指針現在的位置,那麼讓該指針和慢指針同時出發,相遇時的第一個地 方,則是 
環的入口

NODE_T find_loop_entry(NODE_T *head)
{
     NODE_T *fast, *slow;

     int loop = 0;
     if (!list)
         return NULL;

     slow = fast = list;

     while (slow && fast && fast->next) {
         slow = slow->next;
         fast = fast->next->next;
         if (fast == slow) {
             loop = 1;
             break;
         }
     }

     if (loop == 1) {
         fast = list;
         while (slow && fast) {
             slow = slow->next;
             fast = fast->next;
             if (fast = slow)
                 break;
         }
         return fast;
     }
     else
         return NULL;

}

4.查找一個非循環鏈表中的中間節點的值
同樣利用快慢指針,並需要考慮鏈表節點的奇偶性
奇:直接返回慢指針
偶:返回中間兩個節點的平均值
--------------------------------------------
int find_mid_node(NODE_T *head)
{
     NODE_T *fast, *slow;

     if (!head)
         return -1;

     fast = slow = head;

     while (slow && fast) {
         if (fast->next == NULL) /* odd */
             return slow->data;
         else if (fast->next != NULL && fast->next->next == NULL
)
             return (slow->data + slow->next->data)/2;
         else {
             fast = fast->next->next;
             slow = slow->next;
         }
     }

     return -1;
}

5.雙向鏈表操作
------------------------
建立:
typedef struct node_t {
     int data;
     struct node_t *priou;
     struct node_t *next;
}NODE_DUAL;

int create_dulist(NODE_DUAL **head, int value)
{
     *head = (struct node_t *)malloc(sizeof(struct node_t));

     if (*head == NULL) {
         fprintf(stderr, "requst dual direct list failed\n");
         return -1;
     }
     else {
         (*head)->value = value;
         (*head)->next = (*head);
         (*head)->priou = (*head);
         return 0;

     }

}

6.雙向鏈表的插入
-------------------
int insert_dulist(NODE_DUAL *head, int i, int value)
{
     NODE_DUAL *list;
     NODE_DIAL *pn;
     int n = 0;;

     if (head == NULL && i < 1)
         return -1;

     list = head;

     while (list != NULL && n < i - 1) {
         list = list->next;
         n++;
     }

     if (list == NULL)
         return -1;
     pn = (NODE_DUAL *)malloc(sizeof(NODE_DUAL));
     if (pn == NULL)
         return -1;
     else {
         pn->value = value;
         pn->priou = list->prios;
         list->prios->next = pn;
         pn->next = list;
         list->priou = pn;

         return 0;
     }

}

7.獲取指定節點
--------------------------
NODE_DUAL *get_dulist(int cursor)
{
     /* FIXME... */
}

8.刪除指定節點元素
------------------

int del_dulist(NODE_DUAL *head, int cursor)
{
     NODE_DUAL *pn;

     pn = get_dulist(cursor);
     if (pn == NULL)
         return -1;

     else {
         pn->priou->next = pn->next;
         pn->next->priou = pn->priou;
         free(pn);
         return 0;
     }
}

--------------------------------
typedef struct node_t {
     int data;
     struct node_t *next;
}NODE_T;

使用一個指針不斷步進,當該指針等於NULL則說明不是循環鏈表
如果某次該指針等於頭結點,則說明是循環鏈表
----------------------------------------------------------
int is_looplist(NODE_T *head)
{
     NODE_T *list;

     if (!head)
         return -1;

     list = head->next;

     while(list && list != head) {
         list = list->next;
     }

     if (!list)
         return -1;

     else /* exsit backloop */
         return 1;
}

2.鏈表是否存在環,使用網上流傳的快慢指針,慢指針步長爲1,慢指針步長爲2
因此,快指針肯定比慢指針先進入環(並死循環在環裏),當慢指針進入環後,總會 
和快指針相等,此時可以判斷該鏈表存在環
------------------------------------
int is_looplist(NODE_T *list)
{
     NODE_T *fast, *slow;


     if (!list)
         return -1;

     fast = list;
     slow = list;

     while (slow && fast && fast->next) {
         slow = slow->next;
         fast = fast->next->next;
         if (fast == slow)
             return 1;
     }

     return 0;
}

3.鏈表中環入口的查找,同樣使用快慢指針
慢指針步長爲1,快指針爲2
---------------------------------------
假設,環入口的距離爲L,慢指針在環內走的距離爲l,
L+l = N , N爲慢指針走的總步長,此時快指針的總步長爲2N, 慢指針再步進N步 
還是會到達該點(N + N = 2N)
此時,如果讓另外一個指針指向頭節點,然後以步長爲1的長度走N步,也會到達慢 
指針現在的位置,那麼讓該指針和慢指針同時出發,相遇時的第一個地 方,則是 
環的入口

NODE_T find_loop_entry(NODE_T *head)
{
     NODE_T *fast, *slow;

     int loop = 0;
     if (!list)
         return NULL;

     slow = fast = list;

     while (slow && fast && fast->next) {
         slow = slow->next;
         fast = fast->next->next;
         if (fast == slow) {
             loop = 1;
             break;
         }
     }

     if (loop == 1) {
         fast = list;
         while (slow && fast) {
             slow = slow->next;
             fast = fast->next;
             if (fast = slow)
                 break;
         }
         return fast;
     }
     else
         return NULL;

}

4.查找一個非循環鏈表中的中間節點的值
同樣利用快慢指針,並需要考慮鏈表節點的奇偶性
奇:直接返回慢指針
偶:返回中間兩個節點的平均值
--------------------------------------------
int find_mid_node(NODE_T *head)
{
     NODE_T *fast, *slow;

     if (!head)
         return -1;

     fast = slow = head;

     while (slow && fast) {
         if (fast->next == NULL) /* odd */
             return slow->data;
         else if (fast->next != NULL && fast->next->next == NULL
)
             return (slow->data + slow->next->data)/2;
         else {
             fast = fast->next->next;
             slow = slow->next;
         }
     }

     return -1;
}

5.雙向鏈表操作
------------------------
建立:
typedef struct node_t {
     int data;
     struct node_t *priou;
     struct node_t *next;
}NODE_DUAL;

int create_dulist(NODE_DUAL **head, int value)
{
     *head = (struct node_t *)malloc(sizeof(struct node_t));

     if (*head == NULL) {
         fprintf(stderr, "requst dual direct list failed\n");
         return -1;
     }
     else {
         (*head)->value = value;
         (*head)->next = (*head);
         (*head)->priou = (*head);
         return 0;

     }

}

6.雙向鏈表的插入
-------------------
int insert_dulist(NODE_DUAL *head, int i, int value)
{
     NODE_DUAL *list;
     NODE_DIAL *pn;
     int n = 0;;

     if (head == NULL && i < 1)
         return -1;

     list = head;

     while (list != NULL && n < i - 1) {
         list = list->next;
         n++;
     }

     if (list == NULL)
         return -1;
     pn = (NODE_DUAL *)malloc(sizeof(NODE_DUAL));
     if (pn == NULL)
         return -1;
     else {
         pn->value = value;
         pn->priou = list->prios;
         list->prios->next = pn;
         pn->next = list;
         list->priou = pn;

         return 0;
     }

}

7.獲取指定節點
--------------------------
NODE_DUAL *get_dulist(int cursor)
{
     /* FIXME... */
}

8.刪除指定節點元素
------------------

int del_dulist(NODE_DUAL *head, int cursor)
{
     NODE_DUAL *pn;

     pn = get_dulist(cursor);
     if (pn == NULL)
         return -1;

     else {
         pn->priou->next = pn->next;
         pn->next->priou = pn->priou;
         free(pn);
         return 0;
     }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章