数据结构之循环链表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;
     }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值