數據結構與算法2——數組

  數組是應用最廣泛的數據存儲結構。它被植入到大部分編程語言中。大部分數據結構都有最基本的四個操作:插入、刪除、查找、修改。對于這四種操作每一種數據結構都有相應的算法。算法和數據結構因此就是非常緊密的相聯系的。

1 數組例子 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

  數組的每一個元素必須是連續,也就是中間沒有洞。就是說第一個元素和第三個元素有值,但不允許第二個元素是空的。

 1 package chapter2;
 2 
 3 public class Array {
 4     public static void main(String[] args){
 5         //創建一個數組
 6         long[] arr;
 7         arr = new long[100];
 8         int nElems = 0;
 9         int j;
10         long searchKey;
11         arr[0] = 99;
12         arr[1] = 11;
13         arr[2] = 22;
14         arr[3] = 33;
15         arr[4] = 55;
16         arr[5] = 66;
17         arr[6] = 44;
18         arr[7] = 77;
19         arr[8] = 23;
20         arr[9] = 88;
21         nElems = 10;
22         //輸出前10位數組元素
23         for(j = 0; j < nElems; j++){
24             System.out.print(arr[j] + " ");
25         }
26         System.out.println();
27         //查找數組的一個元素值為55的元素
28         searchKey = 55;
29         for(j = 0; j < arr.length; j++){
30             if(arr[j] == searchKey){
31                 break;
32             }
33         }
34         if(j == nElems){
35             System.out.println("Can't find the element");
36         }else{
37             System.out.println("find the element " + searchKey + " at index " + (j + 1) );
38         }
39         //刪除指定元素
40         searchKey = 66;
41         for(j = 0; j < arr.length; j++){
42             if(arr[j] == searchKey){
43                 break;
44             }
45         }
46         for(int k = j; k < nElems; k++){
47             arr[k] = arr[k+1];
48         }
49         nElems--;
50         //輸出刪除后的數組
51         for(j = 0; j < nElems; j++){
52             System.out.print(arr[j] + " ");
53         }
54     }
55 }
56 
57 輸出結果:
58 99 11 22 33 55 66 44 77 23 88 
59 find the element 55 at index 5
60 99 11 22 33 55 44 77 23 88 

2 將程序劃分成類 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

上面的程序包含了一個很大的方法,通過將程序劃分成類以后,并且將其中的方法模塊化,這樣程序看起來更加有條理。

 1 package chapter2;
 2 class ArrayMethod{
 3     private long[] arr;
 4     private int nElems;
 5     public ArrayMethod(int max){
 6         arr = new long[max];
 7         nElems = 0;
 8     }
 9     public void insert(long value){
10         arr[nElems] = value;
11         nElems++;
12     }
13     public boolean find(long searchKey){
14         //查找數組的一個元素值為searchKey的元素
15         int j;
16         for(j = 0; j < arr.length; j++){
17             if(arr[j] == searchKey){
18                 break;
19             }
20         }
21         if(j == nElems){
22             return false;
23         }else{    
24             return true;
25         }
26     }
27     //刪除指定元素
28     public boolean delete(long searchKey){
29         int j;
30         for(j = 0; j < arr.length; j++){
31             if(arr[j] == searchKey){
32                 break;
33             }
34         }
35         for(int k = j; k < nElems; k++){
36             arr[k] = arr[k+1];
37         }
38         nElems--;
39         return true;
40     }
41     //輸出數組
42     public void display(){
43         //輸出前10位數組元素
44         for(int j = 0; j < nElems; j++){
45             System.out.print(arr[j] + " ");
46         }
47         System.out.println();
48     }
49 }
50 class HighArray {
51 
52     public static void main(String[] args){
53         int maxSize = 100;
54         ArrayMethod arr = new ArrayMethod(maxSize);
55         arr.insert(99);
56         arr.insert(11);
57         arr.insert(22);
58         arr.insert(33);
59         arr.insert(55);
60         arr.insert(66);
61         arr.insert(44);
62         arr.insert(77);
63         arr.insert(23);
64         arr.insert(88);
65         //輸出數組
66         arr.display();
67         //查找值為55的元素
68         long searchKey = 55;
69         if(arr.find(searchKey)){
70             System.out.println("find the element ");
71         }else{
72             System.out.println("Can't find the element");
73         }
74         //刪除指定元素
75         searchKey = 22;
76         if(arr.delete(searchKey)){
77             System.out.println("Delete the element successfully ");
78         }else{
79             System.out.println("Can't find the element");
80         }
81         //輸出刪除元素后的數組
82         arr.display();
83     }
84 }

3 有序數組 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

  假設一個數組,其中的數據項按關鍵字升序排列,即最小值在下標為0的單元上,每一個單元都比前一個單元的值大。這種數組被稱為有序數組。

  當向這種數組中插入數據項時,需要為插入操作找到正確的位置:剛好在稍小值的后面,稍大值的前面。然后將所有比待茶數據項的值向后移以便騰出空間。
  將數據按順序排列的好處之一就是可以通過二分法查找顯著地提高查找速度。但缺點是降低了插入操作的速度。

4 線性查找 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

  默認情況下是線性查找,線性查找和未經排序的數組的查找操作相似。

5 二分查找 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

  當使用二分查找時就體現有序數組的好處,這種查找比線性查找快很多,尤其是對大數組來說更為顯著。
  二分查找首先從要查找的范圍確定一個中位數,然后比較要找的數和中位數的大小關系,確定更小的范圍,依次遞歸,知道找到那個數。

?

?

?將數目進行放大,可以發現二分查找是極為優秀的

5.1 有序數組的二分搜索代碼 ??

二分查找是將數組數據項范圍不斷對半分隔來查找特定的數據項。方法如下所示:

  1 package chapter2;
  2 class ArrayMethod{
  3     private long[] arr;
  4     private int nElems;
  5     public ArrayMethod(int max){
  6         arr = new long[max];
  7         nElems = 0;
  8     }
  9     public void insert(long value){
 10         arr[nElems] = value;
 11         nElems++;
 12     }
 13     //二分查找法
 14     public int halfFind (long searchKey){
 15         int lowerBound = 0;
 16         int upperBound = nElems - 1;
 17         int curIn;
 18         while(true){
 19             curIn = (lowerBound + upperBound)/2;
 20             if(arr[curIn] == searchKey){
 21                 return curIn;
 22             }else if(lowerBound >= upperBound){
 23                 return nElems;
 24             }else{
 25                 if(arr[curIn] > searchKey){
 26                     upperBound = curIn - 1;
 27                 }else{
 28                     lowerBound = curIn + 1;
 29                 }
 30             }    
 31         }
 32     }
 33     public int size(){
 34         return nElems;
 35     }
 36     public boolean find(long searchKey){
 37         //查找數組的一個元素值為searchKey的元素
 38         int j;
 39         for(j = 0; j < arr.length; j++){
 40             if(arr[j] == searchKey){
 41                 break;
 42             }
 43         }
 44         if(j == nElems){
 45             return false;
 46         }else{    
 47             return true;
 48         }
 49     }
 50     //刪除指定元素
 51     public boolean delete(long searchKey){
 52         int j;
 53         for(j = 0; j < arr.length; j++){
 54             if(arr[j] == searchKey){
 55                 break;
 56             }
 57         }
 58         for(int k = j; k < nElems; k++){
 59             arr[k] = arr[k+1];
 60         }
 61         nElems--;
 62         return true;
 63     }
 64     //輸出數組
 65     public void display(){
 66         //輸出前10位數組元素
 67         for(int j = 0; j < nElems; j++){
 68             System.out.print(arr[j] + " ");
 69         }
 70         System.out.println();
 71     }
 72 }
 73 class HighArray {
 74 
 75     public static void main(String[] args){
 76         int maxSize = 100;
 77         ArrayMethod arr = new ArrayMethod(maxSize);
 78         arr.insert(99);
 79         arr.insert(11);
 80         arr.insert(22);
 81         arr.insert(33);
 82         arr.insert(55);
 83         arr.insert(66);
 84         arr.insert(44);
 85         arr.insert(77);
 86         arr.insert(23);
 87         arr.insert(88);
 88         //輸出數組
 89         arr.display();
 90         //查找值為55的元素
 91         long searchKey = 35;
 92 //        if(arr.find(searchKey)){
 93 //            System.out.println("find the element ");
 94 //        }else{
 95 //            System.out.println("Can't find the element");
 96 //        }
 97         //二分法查找
 98         if(arr.halfFind(searchKey) != arr.size()){
 99             System.out.println("Find it");
100         }else{
101             System.out.println("Can't find it");
102         }
103 //        //刪除指定元素
104 //        searchKey = 22;
105 //        if(arr.delete(searchKey)){
106 //            System.out.println("Delete the element successfully ");
107 //        }else{
108 //            System.out.println("Can't find the element");
109 //        }
110         //輸出刪除元素后的數組
111         arr.display();
112     }
113 }

5.2 有序數組的優點 ? ? ? ? ? ? ?

  使用有序數組最主要的好處是查找的速度比無序數組快多了。不好的方面是在插入操作中由于所有靠后的數據都需要移動以騰開空間,所以速度較慢。有序數組和無序數組中的刪除操作都很慢,這是因為數據項必須向前移動來填補已刪除數據項的洞。有序數組在查找頻繁的情況下十分有用,但若是插入和刪除較為頻繁時,則無法高效工作。

6 大O表示法 ? ? ? ? ? ? ? ? ? ??

  計算機科學中評價算法效率的方法稱為大O表示法。比較算法時候通常會說"算法A比算法B快2倍",這種說法意義不大。因為數據項的變化會對排序造成一定很大影響。有可能數據項增加50%,算法A就比B快了3倍,或者可能只有一半的數據項,A和B的速度是相同的。

6.1 無序數組的插入:常數 ? ??

  無序數組的插入是我們到現在為止所見過的算法中唯一一個與數組項個數無關的算法。新數據項總被放在下一個有空的地方,a[nElems],然后nElems增加。無論數組中的數據項個數N有多大,一次插入總是用相同的時間。我們可以說向一個無序數組中插入一個數據項的時間T是一個常數K
T=K
在現實情況中,插入所需的實際時間與以下這些因素有關:微處理器,編譯程序生成程序代碼的效率,等等。

6.2 線性查找:與N成正比 ? ??

  在數組數據項的線性查找中,我們已經發現尋找特定數據項所需的比較平均次數為數據項總數的一半。因此設N為數據項總數,搜索時間T與N的一半成正比:
T=K*N/2
  同插入一樣,若要得到方程中K的值,首先需要對某個N值的查找進行計時,然后用T來計算K。當得到K后,便可以對任意N的值來計算T。將2并入K可以得到更方便的公式,新K值等于原先的K除以2即
T=K*N
這個方程說明平均線性查找時間與數組的大小成正比。即如果一個數組增大兩倍,則所花費的查找時間也會相應地增長兩倍。

6.3 二分查找:與log(N)成正比

  同樣,我們可以為二分查找指定出一個與T和N有關的公式:T=K*log2(N)
  實際上,由于所有的對數和其他對數成比例(比如從底數2轉換到底數為10需乘以3.322),也可以將這個為常數的底數也并入K。由此不必指定底數:
T=K*log(N)
不要常數
  大O表示法同上面的公式比較類似,但它省去了常數K。當比較算法時,并不在乎具體的微處理器或編譯器;真正需要比較的是對應不同的N值,T是如何變化的,而不是具體的數字,因此不需要常數。
  大O表示法使用大寫字母O,可以認為其含義是order of(大約是)。我們可以使用大O表示法來描述線性查找使用了O(N)級時間,二分查找使用了O(logN)級時間。向一個無序數組中的插入使用了O(1),或常數級時間。

下表總結的是討論過的算法的運行時間


  大O表示法的實質并不是對運行時間給出實際值,而是表達了運行時間是如何受數據項個數所影響的。除了實際安裝后真正去測量一次算法的運行時間之外,這可能是對算法進行比較的最有意義的方法了。

6.4 幾種算法時間復雜度的對比?

?

7 為什么不用數組表示一切? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

  僅使用數組似乎就可以完成所有工作,為什么不用它們來進行所有數據存儲呢?我們已經見到了許多關于數組的缺點。在一個無序數組中可以很快進行插入(O(1)),但是查找卻要花費較慢的O(N)時間。在一個有序數組中可以查找得很快,用O(logN)的時間,但插入卻花費了O(N)時間。對于這兩種數組而言,由于平均半數的數據項為了填補"空洞"必須移動,所以刪除操作平均需要O(N)時間。
  如果有一種數據結構進行任何如插入、刪除和查找的操作都很快(理想的O(1)或是O(logN)時間),那就好了。后面我們會介紹類似的數組,但這是以程序的復雜度為代價的。
  另外數組被創建后,占用內存長度是確定的,無法進行修改,這樣的話,如果創建的長度過大,但是實際需要的很少就會造成內存浪費,如果創建的長度過小,就會造成溢出,無法彈性使用。

轉載于:https://www.cnblogs.com/people/p/3188437.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/378094.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/378094.shtml
英文地址,請注明出處:http://en.pswp.cn/news/378094.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java treemap_Java TreeMap putAll()方法與示例

java treemapTreeMap類putAll()方法 (TreeMap Class putAll() method) putAll() method is available in java.util package. putAll()方法在java.util包中可用。 putAll() method is used to copy all the key-value pairs from the given map (m) and paste it into this map…

LeetCode 167. 兩數之和 II - 輸入有序數組 思考分析

目錄1、暴力&#xff0c;超時2、雙指針滑動窗口條件限制 AC3、觀看題解&#xff08;吸取他人經驗&#xff09;1、二分查找2、雙指針3、雙指針二分查找給定一個已按照升序排列 的有序數組&#xff0c;找到兩個數使得它們相加之和等于目標數。 函數應該返回這兩個下標值 index1 …

敏捷開發用戶故事系列之七:用戶故事與MVC

這是用戶故事系列的第七篇。&#xff08;之一&#xff0c;之二&#xff0c;之三&#xff0c;之四&#xff0c;之五&#xff0c;之六&#xff0c;之七&#xff0c;之八&#xff0c;之九&#xff09;用戶故事和MVC沒有關系&#xff0c;因為MVC是實現方法&#xff0c;因此在思考用…

七、規則組織的衍生組織——菱形斜紋組織數學模型的建立

基礎概念公式推到可參考該專欄下的前幾篇博文。 菱形斜紋組織圖&#xff1a; 分析&#xff1a;首先3上2下2上1下&#xff0c;飛數為1&#xff0c;右斜。kw8表示從左下角開始往上數8格為緯峰所在位置&#xff1b;kj8表示從左上角開始往右數8格為經峰所在位置。 這樣就將菱形斜…

顯卡測試軟件毛毛蟲,超龍超龍,與眾不同,頂流配備,散熱一流,3070Ti超龍旗艦版評測...

可能大家都沒想到此次顯卡荒會持續近一年&#xff0c;還是出現國家級干涉才將這股“歪風”剎住了。而且也僅僅算是剎住了大陸的速度&#xff0c;主要踩死剎車的應該就是黃大廚。他從5月初推出的新核心就采取了出廠即鎖算力的做法&#xff0c;但是即便如此&#xff0c;那些看著高…

poj 2513 Colored Sticks

// 判斷圖是否聯通 在連通的基礎上還要判斷是否存在歐拉通路// 判斷連通就并查集了 判斷是否存在歐拉通路&#xff1a; 點度數為數的點 1 >3就是不存在的 其它是存在的// 我開始用 map 判重 然后就悲劇了一上午 好久沒寫 Trie樹了 都忘了、#include <iostream> #in…

strictmath_Java StrictMath ulp()方法與示例

strictmathStrictMath類ulp()方法 (StrictMath Class ulp() method) Syntax: 句法&#xff1a; public static double ulp(double do);public static float ulp(float fl);ulp() Method is available in java.lang package. ulp()方法在java.lang包中可用。 ulp(double do) Me…

八、非規則組織分析及其數學模型——平紋變化組織

非規則組織顧名思義&#xff0c;無法通過一個數學模型來描述所有的非規則組織、對于每一個具體的非規則組織而言&#xff0c;其也有一定的規律性可循&#xff0c;即可通過分析每一個具體的非規則組織的組織點運動規律來建立相應的數學模型。 一、平紋變化組織 平紋變化組織即…

怎么看xp計算機是32位還是64位,教你查看XP系統的不同32位還是64位詳細的步驟

電腦中使用的不同的版本如果安裝一些大型的游戲的時候都是有技巧來實現的&#xff0c;那在XP電腦中想要知道的對于不同的32位還是64位的版本的文件操作的時候新手是怎么知道自己安裝的軟件的版本呢&#xff0c;今天小編就來跟大家分享一下教你查看XP系統的不同32位還是64位詳細…

微軟面試100題2010年版全部答案集錦(含下載地址)

微軟等數據結構算法面試100題全部答案集錦作者&#xff1a;July、阿財。時間&#xff1a;二零一一年十月十三日。引言無私分享造就開源的輝煌。今是二零一一年十月十三日&#xff0c;明日14日即是本人剛好開博一周年。在一周年之際&#xff0c;特此分享出微軟面試全部100題答案…

get post

1. get是從服務器上獲取數據&#xff0c;post是向服務器傳送數據。2. get是把參數數據隊列加到提交表單的ACTION屬性所指的URL中&#xff0c;值和表單內各個字段一一對應&#xff0c;在URL中可以看到。post是通過HTTP post機制&#xff0c;將表單內各個字段與其內容放置在HTML …

LeetCode 27.移除元素 思考分析

題目 給你一個數組 nums 和一個值 val&#xff0c;你需要 原地 移除所有數值等于 val 的元素&#xff0c;并返回移除后數組的新長度。 不要使用額外的數組空間&#xff0c;你必須僅使用 O(1) 額外空間并 原地 修改輸入數組。 元素的順序可以改變。你不需要考慮數組中超出新長…

九、非規則組織分析及其數學模型——曲線斜紋組織

曲線斜紋組織圖&#xff1a; 因為其形狀酷似拋物線&#xff0c;拋物線又是曲線中的一種&#xff0c;故稱為曲線斜紋組織。 特點&#xff1a;1&#xff0c;每一根經紗上的組織點運動規律不變 2&#xff0c;飛數是變化的&#xff0c;故也稱為變飛數組織 飛數滿足的兩個條件&…

ulp通信_Java Math類ulp()方法及示例

ulp通信數學類ulp()方法 (Math class ulp() method) ulp() method is available in java.lang package. ulp()方法在java.lang包中可用。 ulp() method is used to return the size of a ulp of the given argument, where, a ulp of the given value is the positive distance…

計算機公式column,函數公式的左膀右臂:ROW、COLUMN函數知多少

一個公式生成乘法口訣表演示的公式中用到了兩個函數&#xff1a;ROW和COLUMN&#xff0c;這兩個函數的用途非常廣泛&#xff0c;可以配合其他函數實現很多功能(尤其是和VLOOKUP函數)&#xff0c;另外和這兩個函數相似的還有ROWS和COLUMNS函數&#xff0c;也順便介紹下。函數說明…

apache2.4.x三種MPM介紹

三種MPM介紹 Apache 2.X 支持插入式并行處理模塊&#xff0c;稱為多路處理模塊&#xff08;MPM&#xff09;。在編譯apache時必須選擇也只能選擇一個MPM&#xff0c;對類UNIX系統&#xff0c;…

LeetCode 15. 三數之和 思考分析(雙指針解)

目錄初解&#xff1a;未考慮去重二解&#xff1a;未考慮去重位置三解&#xff1a;AC題目&#xff1a;給你一個包含 n 個整數的數組 nums&#xff0c;判斷 nums 中是否存在三個元素 a&#xff0c;b&#xff0c;c &#xff0c;使得 a b c 0 &#xff1f;請你找出所有滿足條件且…

十、非規則組織分析及其數學模型——鋸齒形斜紋組織

鋸齒形斜紋組織圖&#xff1a; 分析&#xff1a; 前半齒長度k&#xff0c;表示山谷到山峰的列數&#xff0c;也就是鋸齒的寬度&#xff1b; 鋸齒飛數s&#xff0c;表示山峰到山峰的行數&#xff0c;也就是鋸齒的高度。 起始點相差4格&#xff0c;也就是第一部分整體向上移動…

Linq lamdba GroupJoin外連接示例

其實用from..Linq語句做外連接簡單而且便于理解&#xff0c;我個人使用lamdba純粹是技術上的追求吧 DataTable exceldtnew DataTable();DataTable nomacdtnew DataTable();exceldt exceldt.AsEnumerable().GroupJoin(nomacdt.AsEnumerable(), a > a.Field<String>(&q…

ajax為什么有時候不行,為什么不能用ajax調用

Ajax取值時出現未知的運行時錯誤的解決方法在Ajax里經常會通過innerHTML來改變界面&#xff0c;這個比使用DOM要簡單一些。比如&#xff1a;element.innerHTML "put code here"不過&#xff0c;在IE中&#xff0c;有時候會出現"未知的運行時錯誤(unknown runti…