http://dev.firnow.com/course/3_program/c++/cppjs/20081012/150161.html
已知链表的头结点head,写一个函数把这个链表逆序 ( Intel)
Node * ReverseList(Node *head) //链表逆序 { if ( head == NULL || head->next == NULL ) // 否则下面的就错了,一定要注意一些特定条件的判断,边界问题狠重要,软件开发要注意对异常分支的处理 // 三个指针的方式结构比较清晰 Node *p1 = head; Node *p2 = p1->next; Node *p3 = p2->next; p1->next = NULL; while ( p3 != NULL ) { p2->next = p1; // p2->next为p3,已经保存过了 //p1、p2、p3都向前移动一个 p1 = p2; p2 = p3; p3 = p3->next; } p2->next = p1; //最末端节点挂在链上 head = p2; return head; }
已知两个链表head1 和head2 各自有序升序排列,请把它们合并成一个链表依然有序。(保留所有结点,即便大小相同)
Node * Merge(Node *head1 , Node *head2) { if ( head1 == NULL) return head2; if ( head2 == NULL) return head1; // 良好的习惯,指针要初始化为NULL Node *head = NULL; Node *p1 = NULL; Node *p2 = NULL; // 从小到大,获得头节点 if ( head1->data =< head2->data ) { head = head1; p1 = head1->next; // 注意更新的不一样 p2 = head2; } else { head = head2; p2 = head2->next; p1 = head1; } Node *pcurrent = head; while ( p1 != NULL && p2 != NULL) { if ( p1->data <= p2->data ) { pcurrent->next = p1; // 挂接新节点 &n pcurrent = p1; //更新当前最后一个节点 p1 = p1->next; //更新下一个待比较节点 } else { pcurrent->next = p2; pcurrent = p2; p2 = p2->next; } } if ( p1 != NULL ) //挂接剩余部分 pcurrent->next = p1; if ( p2 != NULL ) pcurrent->next = p2; return head; }
已知两个链表head1 和head2 各自升序排列,请把它们合并成一个链表依然有序,这次要求用递归方法进行。 (Autodesk)
递归版本实际上很容易从上面一个版本改动而得来,主要是注意退出的条件和跌代的条件。
Node * MergeRecursive(Node *head1 , Node *head2) {//退出条件是某链结束 if ( head1 == NULL ) return head2; if ( head2 == NULL) return head1; Node *head = NULL; if ( head1->data < head2->data ) { head = head1; head->next = MergeRecursive(head1->next,head2); } else { head = head2; head->next = MergeRecursive(head1,head2->next); } return head; }
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/mumu10/archive/2008/09/05/2886817.aspx
下面有code的地方都经过了验证的 :)
list 的定义
typedef struct{
int val;
struct list *next;
} list;
1. 反转一个链表,循环算法。
list * reserve_list_by_recurrence(list *l)
{
list * l_item = l;
list * n_item = l->next;
while (n_item != 0)
{
list * p_item = l_item;
l_item = n_item;
n_item = l_item->next;
l_item->next = p_item;
}
l->next = 0;
return l_item;
}
2. 反转一个链表,递归算法。
list * reserve_list_by_recursion(list* p_l, list *l, list *n_l)
{
l->next = p_l;
if (n_l != 0)
{
reserve_list_by_recursion(l, n_l, n_l->next);
}
else
{
return l;
}
}
3. 判断一个链表是否有循环。
思路有些意思,code比较简单,就不列code了。
方法1:快慢法,一个以步长为1遍历,一个以步长为2遍历,next为空前相遇即为循环链表。
方法2:破环结构法,遍历链表,修改链表项的某些结构,通常修改next指针,如果遍历完之前,发现有链表项已经修改,则为循环链表。
当然还有更愚蠢的方法3,就不献丑了 :)
4. 两个链表,一升一降,合并为一个升序链表。
没有什么技巧,不写code了。
5. 在双向链表中删除指定元素。
同上 :)
PS. 一些数组相关的也放在这里吧。
1. 一个数组,下标从0到n,元素为从0到n的整数。判断其中是否有重复元素。
定义了个字符串数组,方便返回结果:
char *check_array_repeat_str[3] = {"no repeat","repeat", "error"};
printf ("%s", check_array_repeat_str[check_array_repeat(a, 10)]);
函数:
int check_array_repeat(int a[], int n)
{
int i;
int *flag_array = malloc(sizeof(int) * (n+1));
memset(flag_array, 0, sizeof(int) * (n+1));
for(i=0; i<=n; i++)
{
if ((a[i]>n) || (a[i]<0))
{
return 2; //error
}
if (*(flag_array+a[i]) == 1)
{
return 1; //repeat
}
else
{
*(flag_array+a[i]) = 1;
}
}
return 0;
}