`

重走算法路之用链表排序(一)

 
阅读更多

        昨天把链表敲了一下,我们可以实现一个不要为他内存浪费溢出而伤脑筋的存放数据的结构,我们以前对数据进行排序的时候都是喜欢放在数组里面,用数组来保存我们的排好序的数据,同时在数组中对数组进行操作,实现排序。今天就用昨天的链表来给数据排排序,在插入元素节点的时候就进行判断,然后插入,最后得到的链表也就是一个排好了序的链表。

       用这个思想我们可以把他用到一个高效的排序机制里面,假设有一个无序的数组,我们把他们取出来一个一个的插入到有序链表,在插入的时候他们自动完成了排序,插入完毕之后,把他们从有序链表中删除(删除的时候返回头节点),重新放入数组,经过这样的操作我们就可以完成无序数组的排序了。

        这种排序的方式和数组的插入排序的思想是一样的,但是比数组中的插入排序效率更高一些,主要是复制的次数少一些,在数组中进行插入排序需要一栋N^2次,而在链表中,每一个节点只要复制两次,也就是2N次,一次是从数组到链表,一次是从链表在到数组。虽然他们的时间复杂度还全都是O(N^2)(因为用链表插入每个节点平均还是会和 链表中的N/2个元素进行比较,插入N个元素时间复杂度还是到了O(N^2))但是第二种还是好一点。因为在移动数据这里少了很多时间。

       

    下面把用链表把插入的数据排好序的代码贴出来,可以扩展到对存放到数组中的一组元素进行排序:

       

    先是链表中的节点类:

      

package 有序链表;

/*
 * 节点类,封装了属性
 * @author TMS
 *
 */
public class Link {
	public long data;
	public Link next;         //定义指向下一个节点
	
	/*
	 * 初始化节点的属性
	 */
	public Link(long data) {  
		this.data = data;
	}
   
	/*
	 * 打印出每个节点的信息
	 */
    public void displayLink() {
    	System.out.println("data = "+data);
    }
}

   

    再是主类:关键代码也就是里面的Insert();方法,插入节点后,自动排好序了。

   

package 有序链表;

public class SortLink {
	
	/*
	 * 定义第一个节点
	 */
	private Link first;
	
	/*
	 * 初始化头节点
	 */
	public SortLink() {
		first = null;
	}
	
	/*
	 * 判断是否为空
	 */
	public boolean isEmpty() {
		return first == null;
	}
	
	/*
	 * 插入一个节点,并进行判断,使链表成为有序的
	 */
	public void insert(long data) {
		Link newLink = new Link(data);
		Link old = null;
		Link current = first;
		
		while( current !=null && data>current.data ) {    //遍历进行判断,插入节点
			old = current;                                //先记录当前的节点
			current = current.next;                       //节点依次往下跑
		}
		if(old == null) {                                 //链表中为空的时候
			first = newLink;                              //将新的节点直接赋给第一个节点
		} 
		else {
			old.next = newLink;                           //开始的时候链表就不为空,也就是会将新的
			                                              //元素插入到中间时,原先的节点指向新的节点
			                                              //新的节点指向当前的节点
			newLink.next = current;
		}
	}
	
	/*
	 * 删除头节点
	 */
	public Link remove() {
		Link temp = first;
		first = first.next;
		return temp;
	}
	
	/*
	 * 打印出每个节点,从头节点开始
	 */
	public  void display() {
		Link current = first;
		while(current!= null) {
			current.displayLink();
			current = current.next;
		}	
	}
	
	/*
	 * 测试方法
	 */
	public static void main(String[] args) {
		SortLink sl = new SortLink();
		System.out.println("添加几个节点:");
		sl.insert(2);
		sl.insert(32);
		sl.insert(17);
		sl.insert(18);
		sl.insert(10);
		System.out.println("打印出每个节点,经过排序了的:");
		sl.display();
		System.out.println("<----------------------------------->");
		System.out.println("删除几个节点是从头节点开始删的 :");
		System.out.println("删除一个节点:"+sl.remove().data);
		System.out.println("删除一个节点:"+sl.remove().data);
		System.out.println("打印出每个节点,删除几个节点后:");
		sl.display();
		
	}
}

 

    打印出结果,和上面插入的数据进行比较,看是否排好序了:

    

添加几个节点:
打印出每个节点,经过排序了的:
data = 2
data = 10
data = 17
data = 18
data = 32
<----------------------------------->
删除几个节点是从头节点开始删的 :
删除一个节点:2
删除一个节点:10
打印出每个节点,删除几个节点后:
data = 17
data = 18
data = 32

 

   PS:好了!洗洗睡了!渣渣每天都会来一发,不要说我水。一天的谢幕。

 

1
0
分享到:
评论

相关推荐

    算法导论源码

    1. **排序算法**(sort.cpp):排序是计算机科学中最基础也是最常用的算法之一。在sort.cpp中,可能包含了各种排序算法的实现,如冒泡排序、插入排序、选择排序、快速排序、归并排序、堆排序等。这些排序算法各有优...

    经典算法大全

    《经典算法大全》是一本汇集了多种经典算法的书籍,它包含了从基础的数学序列、排列组合到复杂的递归算法、搜索算法和排序算法等。下面是对书中的部分算法知识点的详细解释: 1. 河内之塔:河内之塔问题,也称为...

    Java常见100多种算法大全

    - **快速排序**:使用分治策略,选取一个基准值,将数组分为两部分,一部分所有元素小于基准,另一部分所有元素大于基准,然后对两部分递归进行快速排序。 - **归并排序**:同样采用分治策略,将数组拆分为小数组...

    C程序算法大全

    **解法**:通过循环结构,使用一个二维数组来存储三角形的每一层,计算每一层的值。 #### 4. 三色棋 三色棋是一种策略游戏,玩家轮流放置棋子,目标是使三个同色的棋子形成一条直线。这个问题可以通过搜索算法来...

    C程序设计-c常用算法程序集

    - **冒泡排序**:这是一种简单的排序算法,通过重复遍历数组,比较相邻元素并交换位置来逐步将较大的元素“冒”到数组的一端。 - **选择排序**:每次从未排序的部分中选取最小(或最大)的元素,放到已排序部分的...

    C常用算法程序集.rar

    《C常用算法程序集》是针对C语言编程者的一个宝贵资源,它包含了各种经典和实用的算法实现。这个压缩包中的文件旨在帮助开发者巩固基础,提高解决实际问题的能力。以下是对压缩包中可能包含的算法及其重要性的详细...

    lintcode阶梯训练美国大公司所有题目代码和笔记合集

    常用的方法是双指针法,一个指针先走N步,然后两个指针同步移动,当先走的指针到达链表尾部时,另一个指针指向的就是待删除的节点。 八、《搜索旋转排序数组——62_search-in-rotated-sorted-array》 在旋转排序...

    数据结构导游代码

    2. **链表**:由一系列节点组成,每个节点包含数据和指向下一个节点的指针。链表在插入和删除操作上比数组更灵活,但随机访问效率较低。 3. **栈**:是一种后进先出(LIFO)的数据结构,常用于函数调用、表达式求值...

    电子技术基础复习题 (2).doc

    可以使用一个指向当前报数人的指针,每次报数后移动指针,直到所有人为零。 3. 单链表就地逆置:这个题目要求不使用额外空间逆置链表。可以通过三个指针(前驱、当前、后继)配合交换指针的方式实现。 4. 建立有序...

    CC++ 技术面试基础知识总结,包括语言、程序库、数据结构、算法、系统、网络、链接装载库等知识及面试经验

    - **链接过程**:编译、汇编、链接三步走,理解符号解析和重定位。 - **装载过程**:了解装载器如何将可执行文件映射到内存中。 面试时,不仅需要理解这些概念,还需要能够分析问题、设计解决方案,并能写出高效...

    微软Java面试题汇总(最新)

    - 使用快慢指针的方法,快指针每次走两步,慢指针每次走一步,若有环则最终会在环内相遇。 - **洗牌算法**: - Fisher-Yates洗牌算法是一种高效的方法,它保证每个排列出现的概率相同。 - **字符串转换为整数**: ...

    ACM培训资料(练就坚实的基础)

    常见的数据结构如数组、链表、树、图等,以及排序、查找、递归、动态规划等算法都至关重要。 ##### 2.3 团队配合 ACM竞赛强调团队合作精神。团队成员之间需要相互信任和支持,分工明确,共同分析问题并制定解决...

    13复试题1

    1、 算一个M的N次方,要求用递归 2、 快速排序算法(要求处理N个数已有序的情况)3、 一个8*8的棋盘上有一个骑士,骑士每次上下左右走一步,要求能不重

    javabitset源码-Study:学习

    少有人走的路 数据结构 队列 集合 链表、数组 字典、关联数组 栈 树 二叉树 完全二叉树 平衡二叉树 二叉查找树(BST) 红黑树 B,B+,B*树 LSM 树 BitSet 常用算法 计数排序 桶排序 基数排序 二分查找 Java 中的排序...

    美团校园招聘历年经典面试题汇总:后台开发岗1

    设置两个指针,先让第二个指针先走k-1步,然后两个指针一起走,当第二个指针到达链表尾部时,第一个指针就指向了倒数第k个节点。 2. **集合类**:Java中的集合类主要包括List、Set和Map三大类。List是有序的集合,...

Global site tag (gtag.js) - Google Analytics