巩固题目:
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;
}
}
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;
}
}