单链表的复杂操作

  • 前言
  • 一、链表反转
  • 1.图解步骤
  • 2.节点的struct结构体类型(自定义数据类型)
  • 3.创建一个节点node
  • 4.反转
  • 二、求相邻两个节点值之和为最大的第一个结点指针
  • 1.图解
  • 2.找
  • 三、将递增有序的A和B合并成一个表A
  • 1.图解
  • 2.合并
  • 总结



前言

提示:本节主要讲单链表的复杂操作,这些内容均为个人学习笔记,理解有限请勿当作参考

学习了,基本的增、删、改、查,及malloc / free 的配对使用,本节学习了更为复杂的单链表操作例如合并两个有序单链表。


提示:以下是本篇笔记正文内容,下面案例均来源于老师课堂

一、链表反转

反转链表,又可以称为翻转或逆置链表。
算法思路:依次取原链表中各结点,将其作为新链表首结点插入H结点之后

1.图解步骤

c鱼的数据结构与算法 c 数据结构教程_结点

2.节点的struct结构体类型(自定义数据类型)

代码如下(示例过程只放出关键代码并不完整代码知悉):

#include <stdio.h>
#include <stdlib.h>

// this is linked list node template
typedef int MY_DATA;
typedef struct Link{
    MY_DATA elem;
    struct Link * next;
}link,*sgllink;

3.创建一个节点node

代码如下(一个node):

// @ create linked list and initialization
sgllink initElem(){
    sgllink t = (sgllink)malloc(sizeof(link));

    if(t == NULL){
        printf("malloc is penny pincher!");
        return t;
    }

    t->elem = 0;
    t->next = NULL;

    return t;
}

4.反转

代码如下 (反转过程,在你建好链表的前提下)

// @ reversal list elements
int revElem(sgllink t){
   sgllink q, p = t->next->next;
   t->next->next = NULL;
   
   if(!p){
       printf("Noting!!!");
       return 0;
   }

   while(p){
       q = p;
       p = p->next;

       q->next = t->next;
       t->next = q;
   }
   return 0;
}

二、求相邻两个节点值之和为最大的第一个结点指针

算法思路:设p,q 分别为链表中相邻两结点指针,求p->data+q->data为最大的那一组值,返回其相应的指针p即可

1.图解

c鱼的数据结构与算法 c 数据结构教程_结点_02

2.找

代码如下(前面步骤相同,直接上正餐)

// @ adj tow elem sub Max
	sgllink adjTowElem(sgllink t){
	    sgllink i, j, k;
	    int sum;
	   
	    if(t == NULL) return NULL;
	    if(t->next == NULL){
	        printf("insingnificance!");
	        return t;
	    }
	
	    printf("1\n");
	    i = t->next;
	    j = t->next->next;
	    k = i;
	    sum = i->elem + j->elem;
	    printf("%d\n",sum);
	    while(j->next != NULL){
	        printf("2");
	        i = i->next;
	        j = j->next;
	        if(sum < i->elem + j->elem){
	            sum = i->elem + j->elem;
	            k = i;
	        }
	    }
	    return k;
	}

三、将递增有序的A和B合并成一个表A

算法思路:设指针p、q分别指向表A和B中的结点,若p->data ≤q->data则p结点进入结果表,否则q结点进入结果表。

1.图解

c鱼的数据结构与算法 c 数据结构教程_结点_03

2.合并

代码如下(老师的代码)

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;
}

总结

通过本节课学到的对链表操作的方法,让我展开了一些想想,使得链表操作更灵活,对单链表的认识更深刻。
弄清楚 node 所包含的两个部分非常重要: 数据|指针 两部分组成一个节点(node),存放在自定的struct 类型中。