用链表写的冒泡排序理解

这是一位师弟问的问题,一段用链表写的冒泡排序。

[1] 为什么要多用一个空的表头?

这是由链表结构造成的,如果要交换p1和p2两个节点,则需要p1的前趋的指针,举例,设原链表为{3,2,1}如果我们要交换3和2,由于3是表头节点,所以需要一个指向3的指针节点,因此这里我们设置了一个空的头节点p1,第一个元素的位置实际上在head->next上。

[2] 释放指针方式解读

delete p;
p=NULL;

最后要释放掉这个空的头节点,先保存下这个地址p1=head,实际表的地址指回原来的位置(head=head->next),然后释放p1的指针,释放指针实际就是让p1不要指向head。如果你直接head’=head->next,虽然我们不知道原来的head在哪里了,但是它仍然是指向现在的head‘的,这就是所谓的野指针,这就涉及到指针的知识了,学生党写写程序没关系,但是放到项目里面,就非常不好了。关于这个在指针学习系列里面我再仔细写写。
[3] 总结

熟悉用数组写的冒泡,用算法的思路去思考这个问题,或者写个简单的序列手动模拟程序排序的过程或者让程序输出来排序的过程,便于理解。

时间: 2024-10-14 20:34:26

用链表写的冒泡排序理解的相关文章

用链表写的学生管理系统 成绩的录入与查询都已经是实现了

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct teacher { char name[32]; int math; int english; int data; struct Node *next; }SLIST; int Creat_SList(); int SList_Print(); int SLis

20190125-找到列表第二大的数以及自己写一个冒泡排序

1. 给定一个列表,找出列表第二大的值 思路:考虑列表是可能是乱序列表,并且可能存在两个相等的最大值的情况. s1 = [34,33,2,1,6,7,7,44,3,23,23] 解法1:去重(解决可能存在两个相等的最大值),然后使用sort排序,然后然后通过切片取到第二大的值.tip,一定要先去重再排序,如果先排序再去重可能会打乱序列 s1 = [34,33,2,1,6,7,7,44,3,23,23] s2 = list(set(s1)) s2.sort() print(s2[-2]) #s2[

链表算法递归的理解

一:前言 今天在博客园里面看了一篇文章http://www.cnblogs.com/huangxincheng/p/4051854.html(单链表的倒置),其实自己看了一个小时最后那点还是没看明白,自己的不明白在于,递归调用到最后执行递归下面的代码是怎么执行的,如果执行了,执行时的数据从哪来的?我就是这点想不明白,但是我自己能看懂这个代码.此时的想不明白不知道算不算钻牛角尖.还是先说说自己的理解吧!!! 二:我把他的那段代码复制过来了,单链表我自己又随便写个是:9---->6------->

Windows核心编程02-记事本写代码深入理解cl.exe和link.exe

接下来用记事本手写代码: 1,建一个空的记事本,敲入以下代码 #include "windows.h" int WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine, int cmdShow) { MessageBox(NULL,"HelloWorld!","Info",MB_ABORTRETRYIGNORE|MB_ICONINFORMATION); return

基于无头节点的单链表的升序冒泡排序(C++实现)

由于基础代码的特殊(链表为无头链表),以下冒泡排序算法采用两种方式进行排序.首先对首节点往后的所有节点进行排序,这里使用的是对其索引顺序改变的方法.然后对首节点进行排序,只需要一次循环即可,这里使用的是对节点中的数值进行交换的方法. 1 #include <iostream> 2 using namespace std ; 3 4 #define ERROR -1 5 #define CORRECT 1 6 7 //定义 8 struct LNode { 9 int data ; 10 LNo

c语言 链表 写通讯录

/*   实现一个通讯录: 通讯录可以用来存储1000个人的信息,每个人的信息包括: 姓名.性别.年龄.电话.住址 提供方法: 1. 添加联系人信息 2. 删除指定联系人信息 3. 查找指定联系人信息 4. 修改指定联系人信息 5. 显示所有联系人信息 6. 清空所有联系人  */ #include<stdio.h> #include"phone_book.h" #include<string.h> #include<assert.h> typede

学习手写vue,理解原理

class Compiler{ constructor(el,vm){ // 判断el属性 是不是 一个元素, 如果不是就获取 this.el = this.isElementNode(el)?el:document.querySelector(el); // console.log(this.el); this.vm = vm; // 把当前节点放到内存中 let fragment = this.node2fragment(this.el); // console.log(fragment,"

链表版冒泡排序

基本原理就是尾插法建立链表(当然,也可以用头插法建立链表),重点是冒泡排序法中的两层for循环的参数设置,设置两个链表指针p.q: 第一个用来指向头结点后一个(p = head ->next)(p还有个作用就是排序的步骤数),第二个用来指向头结点后一个的后一个(q = p -> next),每次内层循环q指针往后移一个结点,然后和第一个节点存储的数据相比较,完成交换,直到第一次排序完毕为止,整个过程中,p指针一直指向的是第一个数.第二次,p就指向后一个节点,q指向p所指向的节点的后一个节点,然

java实现双链表(差点没写吐系列...)

刚才把单链表写完了,现在又把双链表写了,双链表和单链表的区别就是每个节点有prior和next两个指针,不同于单链表的一个next指针,而且,正是因为有这两个指针,所以双链表可以前后两个方向去移动指针, 同时,我所实现的双链表和单链表不同之处在于,主要体现在其不用每次都把指针从头结点开始遍历,而是根据实际情况从选择最优的线路去遍历,移动到想要的位置.差点写吐了....话不多说,上代码 1 package com.voole.linkedlist; 2 3 public class Test {