鞏固題目:
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;
}
}
數據結構之循環鏈表05
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章