数据结构——单链表反转、相邻节点最大值、有序链表合并
一.单链表的反转
1.我门需要考虑特殊情况,链表H==NULL;H为空,H只有一个节点,这三种情况我们都不需要进行反转。
2.不是上面三种情况,就进行处理,用一个指针p指向链表第二个节点,之后在第一个节点处将链表断开
3.使用头插法将节点插入新链表,使用新指针q指向p,p就可以往后走,q就插入新链表,之后q再次指向p,一直循环知道p指向NULL
nt list_reverse(linklist H){
linklist p;
linklist q;
if(H==NULL){
printf("H is NULL");
retrun -1;
}
if(H->next==NULL||H->next->next==NULL)
{
return 0;
}
p=H->next->next;
H->next->next=NULL;
while(p!=NULL){
q=p;
p=p->next;
q->next=H->next;
H->next=q;
}
return 0;
}
int list_reverse(linklist H){linklist p;linklist q;if(H==NULL){printf("H is NULL");retrun -1;}if(H->next==NULL||H->next->next==NULL){return 0;}p=H->next->next;H->next->next=NULL;while(p!=NULL){q=p;p=p->next;q->next=H->next;H->next=q;}return 0;
}
二.求链表相邻节点的最大值
思路:
使用三个指针,其中两个位快慢指针(p块指针、q慢指针),r指针用于记录相邻节点最大值的第一个指针。
在一个while循环中不断的取两个相邻节点的值,与sum进行比大小。使用一个零时变量sum记录最大值,每次出现新的最大值是就更新sum和r,一直到快指针p指向NULL退出循环,返回指针r。
while(p->next!=NULL){
p=p->next;
q=q->next;
if(sum<(p->data+q->data)){
sum=p->data+q->data;
r=q;
}
}
注意点:
需要考虑特殊情况,链表创建不正确
if(H==NULL){
printf("H is NULL");
return NULL;
}
链表为空,链表只有一个或两个节点
if(H->next==NULL||H->next->next==NULL||H->next->next->next==NULL)
{
return H;
}
思考:我们上面使用的函数时返回最大值之后的第一个节点,不能知道最大值之和多少,我们如何返回最大值?
使用参数带回,这个参数返回一个地址就行
linklist list_adjmax(linklist H,data_t *value){linklist p,q,r;int sum;if(H==NULL){printf("H is NULL");return NULL;}if(H->next==NULL||H->next->next==NULL||H->next->next->next==NULL){return H;}p=H->next->next;q=H->next;r=q;sum=p->data+q->data;while(p->next!=NULL){p=p->next;q=q->next;if(sum<(p->data+q->data)){sum=p->data+q->data;r=q;}}*value=sum;return r;
}
三.有序链表合并
先创建两个有序链表
nt main()
{linklist H1,H2;int a[]={1,4,6,8,10};int b[]={2,4,16,18,30};int i;H1=list_create();if(H1==NULL){return -1;}H2=list_create();if(H2==NULL){return -1;}for(i=0;i<sizeof(a)/sizeof(int);i++){list_tail_insert(H1,a[i]);}for(i=0;i<sizeof(b)/sizeof(int);i++){list_tail_insert(H2,b[i]);}list_show(H1);list_show(H2);list_free(H1);list_free(H2);return 0;
}
之后调用list_meger();这个函数代码编写过程如下
p=H1->next;q=H2->next;
r=H1;
H1->next=NULL;H2->next=NULL;
此时得到如上图的两个链表,我们创建两个指针,分别指向两个链表的第一个节点,之后就可以将H1、H2两个链表置空,变成空链表,之后去比较,谁小谁放进来(尾部插入)
int list_merge(linklist H1,linklist H2){linklist p,q,r;if(H1==NULL||H2==NULL){printf("H1||H2 is NULL\n");return -1;}p=H1->next;q=H2->next;r=H1;H1->next=NULL;H2->next=NULL;while(p&&q){//都不为空if(p->data<=q->data){r->next=p;p=p->next;r=r->next;r->next=NULL;}else{r->next=q;q=q->next;r=r->next;r->next=NULL;}}if(p==NULL){r->next=q;}else{r->next=p;}return 0;}