1. 程式人生 > >我在北京找工作(三):java實現演算法 直接插入排序+不可變類

我在北京找工作(三):java實現演算法 直接插入排序+不可變類

2013年9月3日 貌似看的排序演算法實現的有點沒難度,但還是一步一步穩紮穩打的來。

1、直接插入排序

直接插入排序(Insertion Sort)的基本思想:將陣列分為有序區和無序區,每次將一個無序區的元素安琪關鍵字大小插入到有序區的適當位子,知道無序區元素個數為0,則排序完成。

同樣的,我們設陣列長度為N。
實現步驟:
<1> 初始時,下標為0的元素,也就是陣列中的第一個元素自成有序區,其餘皆為無序區元素。
<2> 將無序區的第一個元素插入到當前有序區的適當位置中,有序區間長度+1
<3> 重複第<2>步,直到無序區元素個數為0,則排序完成!

還是一些嚴格按照定義步驟進行編寫的程式碼(依舊是預設為從小到大排序)........:

//直接插入排序基礎版
	public void insertSort(int[] arr) {
		int j=-1;
		int k=-1;
		//迴圈預設從arr[1]開始排序,因為預設初始時arr[0]自成有序區
		for(int i=1;i<arr.length;i++) {
			//j控制迴圈層 為arr[i]在當前有序區為之尋找一個合適的插入位子
			for(j=i-1;j>=0;j--) {
				if(arr[j]<arr[i]) break ;
			}
			//如果找到了一個合適的位子,並且不是當前元素的正前方一個
			if(j!=i-1) {
				//將有序區中插入位子之後的所有元素向後移動,騰出空間
				int temp = arr[i] ;
				for(k=i-1;k>j;k--) {
					arr[k+1]=arr[k] ;
				}
				//最後將arr[i]放到正確的位子上即可
				arr[k+1] = temp ;
			}
		}
	}


不知道讀者有沒有注意到,前面的程式碼只是嚴格按照直接插入排序的定義來編寫的,一步一步的實施,雖然次序井然有序。而且也明確的分工流水線。但是如此冗長的程式碼,依舊是不夠清晰的!能夠對其進行改寫的方法有很多:
1)我們完全可以將搜尋和後面的元素後移這兩步進行同步操作(這裡所說的同步和系統級別的執行緒級別的同步完全沒有關係),h合併為一個步驟。
即,向前搜尋一個,比之大的就直接後移一個位子。一邊搜尋,一邊後移。這樣之後,當找到合適的位子之後只需要直接插入就行了!!!

下面給出實現:

//合併搜尋和移位的直接插入排序
	public void insertSort2(int[] arr) {
		int j= -1;
		for(int i=1;i<arr.length;i++) {
			if(arr[i]<arr[i-1]) {
				int temp = arr[i] ;
				//一邊搜尋+同時右移元素
				for(j=i-1;j>=0&&arr[j]>temp;j--) {
					arr[j+1] = arr[j] ;
				}
				//找到位子,直接插入元素
				arr[j+1] = temp ;
			}
		}
	}


可以看到,程式碼簡單了許多。如果對於一些想要死記硬背的記住排序程式碼的屌來說,這可是難記了很多,但是對於通過原理摸索實現的猿們,這同樣是輕鬆了許多。
所以還是不可不強調,通曉原理,才是學習的最好方法!!! 

 別再抱怨啦,,,,,啦啦啦   德瑪西亞~~~

還有一種改寫方法,是看別人的程式碼是想到的:
2)原理很簡單,就是在前一種的基礎上,用元素交換代替掉元素右移。
程式碼嘛? 小二在這裡就不給了,讀者們自己也該去敲敲程式碼了,每天敲敲程式碼,神清氣爽,倍兒爽!   哈哈[email protected]

下面想說的一點就是半個月前看到的別人問的一個問題,於是去網上看了一些資料。有個概念叫“不可變類”。

2、不可變類
java自帶的如:String、還有其餘包裝類Integer、Double都是不可變類。所謂不可變,簡單的說就是其在建立物件之後,其屬性值將不能在物件層面上發生改變。
如果要改變它的值,那肯定就是另外一個物件了。不知道這樣通俗的理解會不會引來 嘲諷 0.0
這也是一個面試時可能會接觸的知識點,所以直接上程式碼掩演示了:

package net.mldream;

public final class NoChangeClass {
	/*
	 * 如何建立一個不可變類 四步驟
	 */
	//1、所有成員都是Private的
	private String userName ;
	private int[] myArray ;
	//2、不對外提供對成員進行改變的方法,如setUserName(..)、setMyArray(..)等
	
	//3、確保所有的類方法都不能被過載,有兩種方法。
	//一:使用final Class(強不可變類)
	//二:將該類的所有方法加上final(弱不可變類)
	public String toString() { 
		StringBuffer sb = new StringBuffer("This is : ");
		sb.append(this.userName+" Number are:") ;
		for (int i = 0; i < myArray.length; i++) { 
			sb.append(myArray[i] + " ");
		}
		return sb.toString();
	}
	//4、如果類的某一個成員變數不是原始型別(primitive)或者不可變類,
	//則必須通過在成員初始化(in)或get方法(out)時通過深度複製(clone)方法,確保類的不可變
	public NoChangeClass(int[] myArray,String userName) {
		this.myArray = myArray.clone();
		this.userName = userName ;
	}

	public static void main(String[] args) {
	}
}


有興趣的讀者一定要自己去試試,並且能夠很好的理解通透其中的原理實現。 如果有什麼不理解的,也可以來和我交流。。
歡迎歡迎~~~~~   今天就到這裡吧~  Good Good study,Day Day up!

相關推薦

北京工作java實現演算法 直接插入排序+可變

2013年9月3日 貌似看的排序演算法實現的有點沒難度,但還是一步一步穩紮穩打的來。 1、直接插入排序 直接插入排序(Insertion Sort)的基本思想:將陣列分為有序區和無序區,每次將一個無序區的元素安琪關鍵字大小插入到有序區的適當位子,知道無序區元素個數為0,

一起學HadoopHadoop叢集的最簡化部署

在和我一起學Hadoop(二):Hadoop的原始碼構建章節中我們構建了適合本地Linux的hadoop-xxx.tar.gz的安裝包。 解壓到安裝目錄 配置如下 環境變數配置 /etc/profile export HADOOP_CONF_DIR=

《你的月亮的C》scanf 的那些事

1、用scanf("%d\n", &i);來輸入數字,要多輸入一行才返回,為什麼? 輸入4之後,要多輸入一個換行和1,才能輸出4。 這是因為,在scanf語句中“\n”不是表示換行符,而是表示讀取並放棄連續的空白字元。scanf語句中任何的空白字元都表示讀

ElasticSearchJava操作ElasticSearch索引之CRUD

transport delete end std testin python網絡 search ava socket 1 package com.gxy.ESChap01; 2 3 import java.net.InetAddress; 4 impor

Java併發synchronized實現原理

一、synchronized用法 Java中的同步塊用synchronized標記。 同步塊在Java中是同步在某個物件上(監視器物件)。 所有同步在一個物件上的同步塊在同時只能被一個執行緒進入並執行操作。 所有其他等待進入該同步塊的執行緒將被阻塞,直到執行該同步塊中的執行緒退出。 (注:不要使用全

數值分析C++實現線性方程組的高斯-賽德爾迭代法

線性方程組的直接解法之後,就輪到迭代解法了,直接解法針對的是低階稠密矩陣,資料量較少,而工程上有更多的是高階係數矩陣,使用迭代法效率更高,佔用的空間較小。 迭代法的最基本思想就是由初始條件,比如說初始解向量隨便列舉一個,就0向量也行,然後進行迭代,k到k+1,一步一步從k=1開始去逼近真實解

胡八一之Javajava集合概述

JAVA集合概述 (一)、Collection 和Iterator介面 import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; public class Te

python3.5《機器學習實戰》學習筆記k近鄰演算法scikit-learn實戰手寫體識別

轉載請註明作者和出處:http://blog.csdn.net/u013829973 系統版本:window 7 (64bit) 我的GitHub:https://github.com/weepon python版本:python 3.5 IDE:Spy

編碼Java Web編碼問題

問題描述: 今天在測試產品的時候發現使用HttpUrlClient傳送POST表單資料,當資料量>=1M的時,後臺報錯,原因分析如下: 一、HTTP協議對資料大小的限制 根據RFC規定,HTTP1.1本身並沒有對GET和POST方法進行引數大小限

Java高併發程式設計學習筆記Java記憶體模型和執行緒安全

文章目錄 原子性 有序性 可見性 – 編譯器優化 – 硬體優化(如寫吸收,批操作) Java虛擬機器層面的可見性 Happen-Before規則(先行發生) 程式順序原則: volat

機器學習感知器演算法實現鳶尾花分類專案實戰

上一章我們已經介紹了感知器演算法規則,並且用python語言實現了。現在我們應用感知器學習規則進行鳶尾花分類實驗。 測試資料我們從鳶尾花資料集中挑選出了山鳶尾(Setosa)和變色鳶尾(Versicolor)兩種花的資訊作為測試資料。雖然感知器並不將資料樣本特

Java基礎總結從0開始Java反射原理

反射:Java虛擬機器允許執行時獲取類的資訊。  2.1 反射的常用方法:        a.forName(String className) :           返回與帶有給定字串名的類或介面相關聯的 Class 物件。        b.forName(String

C++實踐C++實現加密演算法AES

本篇主要講2015年寫的加密演算法。包括:AES,AES-CMAC,HMAC,基於RSA與HMAC的數字簽名演算法。當時大概寫了2天。哈哈! AES演算法 AES是一個對稱加密標準,用以取代DES的商業應用。其分組長度為128位,192位或者256位。

redis使用事務,過期時間,排序,訂閱/釋出,持久化

一.事務 MULTI COMMAND1 COMMAND2 … COMMANDn EXEC 或者 DISCARD (取消) 127.0.0.1:6379> multi

數據結構------------------二叉查BSTjava實現

鏈接 oot 才會 empty rabl 輸出 nbsp ati 數量 數據結構------------------二叉查找樹(BST)的java實現   二叉查找樹(BST)是一種能夠將鏈表插入的靈活性和有序數組查找的高效性相結合的一種數據結構。它的定義如下:   二叉查

HTTP詳解JAVA實現HTTP請求

通過上幾篇的文章,我們對HTTP已經已經有了一個初步的認識,對於"為什麼要用HTTP","怎麼用HTTP","HTTP是什麼"相信大家都有了一個了一個屬於自己的看法,今天這篇文章主要是程式碼的角度上去實現HTTP的請求。

演算法導論》紅黑樹詳解Java實現Demo

使用Java簡單地實現紅黑樹,程式碼如下: /** * 紅黑樹實現demo */ public class RedBlackTree<Key extends Comparable<Key>> { private stati

的BRF+自學教程動態技術

-a gid values 條目 its ans sta sym 函數 開發者們可以在編程中使用各種動態技術,比如RTTS,比如通過動態的類創建和多態來實現功能的平滑擴展。BRF+對象也有一定動態能力。本文將介紹3種不同場景下的動態實踐方式。其中第一種是純配置的,第二和第三

網路程式設計基礎【day10】是一個程序

一、引子 我聽說我的祖先們生活在專用計算機裡, 一生只幫助人類做一件事情,比說微積分運算 了、人口統計了 、生成密碼、甚至通過織布機印花 !   如果你想在這些專用“計算機”上乾點別的事兒,例如安裝個遊戲玩玩, 那是絕對不可能的, 除非你把它拆掉, 然後建一個全新的機器。  

對hyperledger fabric1.1.0的執著執行e2e_cli測試案例以及踩過的坑

1、執行e2e_cli案例: (1.1)下載平臺特定二進位制檔案,如圖下載對應版本,下載地址為: https://nexus.hyperledger.org/content/repositories/releases/org/hyperledger/fabric/hyperledger-fa