数据结构之链表

目录

1.链表的定义,优劣势,基本实现看以往博客;

2.以下介绍关于链表的特殊操作:


 

1.链表的定义,优劣势,基本实现看以往博客;

2.以下介绍关于链表的特殊操作:

1)单链表的反向输出:

实现思想:利用了递归的思想(或者说栈的后进先出的特点)

实现要点:怎么理解这里的递归,怎么用?递归的结束标志是什么?上代码:

void printReverse(Node* p) {
	if (p == NULL) {
		return;
	}
	printReverse(p->next);
	printf("%d ", p->data);
}

这里递归的结束点就是return,向主调返回。具体怎么实现就是这样,通过先递归后输出就可以实现从后往前输出;

2)单链表的反转:

实现思想:找到前面的结点和后面的结点,让后面的结点连接前面的结点,确保后面的后面的结点不丢失,所以还需要一个结点记住;

实现要点:结点反转操作的步骤不能随意改变。上代码:

void reverse() {
	if (head == NULL) {
		printf("没有链表,还无法反转!");
		return;
	}

	Node* pre = head;
	Node* temp = head->next;
	Node* tail = temp->next;

	pre->next = NULL;

	while (temp != NULL) {
		tail = temp->next;
		temp->next = pre;
		pre = temp;
		temp = tail;
		//上面是让tail一直在temp的后面;
		// 两个想法最后达到的效果一样,为什么下面会报错;
		//我是想着,三个指针同时动,每次都移动一位;
		/*temp->next = pre;
		pre = temp;
		temp = tail;

		if (temp == NULL)
		{
			break;
		}

		tail = tail->next;*/
	}
	head = pre;

}

上面的注释部分就是一个错误演示:会导致空指针赋值的异常。

3)单链表的归并排序

实现思想:主要还是递归。通过每一层函数实现分区的操作,并对两个有序链表地分区进行合并,不断地把一个链表拆分为多个小分区。

实现要点:首先,准备一个函数用来合并两个有序链表。其次,准备中间值分区函数。最后定义排序函数,先上代码:

struct ListNode* findMid(struct ListNode* head);
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2);

struct ListNode* sortList(struct ListNode* head) {
    if(head == NULL||head->next == NULL){
        return head;
    }

    struct ListNode* middle = findMid(head);
    struct ListNode* right = middle->next;
    middle->next = NULL;

    struct ListNode* left = sortList(head);
    struct ListNode* sortedRight = sortList(right);

    return mergeTwoLists(left,sortedRight);
}

struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
    //利用递归思想:
    //每一层只需要返回一个链表就行了
    //上一层只需要 next = 下一层的链表;
    if(list1 == NULL){
        return list2;
    }
    if(list2 == NULL){
        return list1;
    }

    if(list1->val<=list2->val){
        list1->next = mergeTwoLists(list1->next,list2);
        return list1;
    }
    else{
        list2->next = mergeTwoLists(list2->next,list1);
        return list2;
    }
}

struct ListNode* findMid(struct ListNode* head){
//找中间;
    struct ListNode* k = head->next;
    struct ListNode* m = head;
    while(k && k->next){
        m = m->next;
        k = k->next->next;
    }
    return m;
}

来解释一下代码:

1.findMid函数就是找到链表中间值,通过快指针“一步两块”,慢指针“一步一块”,当快指针走到null或者,他的next走到null;那么慢指针处就是中间点。

2.mergeTwoLists函数作用:合并两个有序链表。如果只有单个链表返回就行。如果确实有两个有序链表合并,我们就用递归的思想(这里假设升序),如果list1的数据<=list2的数据,那么,就把list1的结点单独拿出来,再调用函数,参数为list1->next和list2,每一层返回一个链表,最后就输出了.

3.sort函数其实就是先分区,再合并,但是由于合并操作在最后,所以其实是把链表先分到实在不能再分,然后逐层合并返回.

 

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值