數據結構Java實現01----算法概述

 

【聲明】 html

歡迎轉載,但請保留文章原始出處→_→ java

生命壹號:http://www.cnblogs.com/smyhvae/算法

文章來源:http://www.cnblogs.com/smyhvae/p/4724692.html
編程

 

【正文】 

 

 

1、數據結構涵蓋的內容:數組

1b51b02a-9151-485c-8bf5-74868f49bf06

 

2、算法的基本概念:數據結構

一、算法的概念:編程語言

Algorithm,是對特定問題求解步驟的一種描述,它是指令的有限序列,其中每一條指令表示一個或者多個操做。ide

二、算法的特性:函數

  • 有窮性:指令序列是有限的
  • 肯定性:每條語句的含義明確,無二義性
  • 可行性:每條語句都應在有限的時間內完成
  • 輸入:零個或者多個輸入
  • 輸出:一個或者多個輸出

三、算法與程序的區別:性能

程序:

  (program)程序是軟件開發人員根據用戶需求開發的、用程序設計語言描述的適合計算機執行的指令(語句)序列。

程序包含的四個要素:

數據結構

算法

程序設計方法

編程語言

程序與算法不一樣。程序是算法用某種程序設計語言的具體實現。程序能夠不知足算法的有窮性,好比操做系統也是一種程序,若是你願意,你的電腦能夠一直開着,保持操做系統的運行。

好比:

while(true)

{

...

} //是一段程序,但不是一個算法

 

四、程序、算法、軟件之間的關係:

程序:算法的計算機實現。用某種編程語言實現。

算法:表示問題的解。

軟件:程序+文檔

以下圖所示:

fe13a77a-f221-42ae-b8de-d8fa6ebedbc3

程序設計=數據結構+算 法

 

3、數據類型:

一、數據類型:

是指一個值的集合和定義在集合上的操做集合。例如:java的整數類型(Integer),就不只僅表示整數數值的集合,還包括對整數類型進行的操做集合,加、減、乘、除、模等操做。

咱們一般所指的數據類型是某種高級語言支持的基本數據類型。  好比java的基本數據類型:int、double、float、char等等。

Java中的數據類型:

37b7135d-9806-4305-be74-c2abb4ab5c23

二、抽象數據類型:

一個數學模型以及定義在這個模型上的一組操做(由用戶定義,用以表示應用問題的數據模型)。

看起來抽象數據類型和數據類型的定義基本相同。不一樣點在於:數據類型一般是指某種高級語言的,而抽象數據類型用戶從新設計,一種概念。這裏的"抽象"的含義在於數學抽象。

  • 原子類型:好比整型
  • 固定聚合類型:好比複數,兩個實數肯定的次序構成
  • 可變聚合類型:好比汽車類型,構成的成分是不肯定的。(由於小轎車、大卡車的構成是不一樣的)

抽象數據類型抽象的層次越高,那麼可複用性也越高。好比:java中的Object是對全部對象的抽象,那麼就能夠做爲全部類的父類。

 

4、抽象數據類型的表示(代碼舉例):

  • C語言使用結構體
  • Java語言使用類

下面分別用C語言與java語言,來定義學生抽象數據類型。已知學生的信息以下:

學號:111222

姓名:生命壹號

性別:男

出生日期:1991-11

專業:電子與通訊工程(計算機方向)

電子郵箱:smyhvae@163.com

 

一、用C代碼定義一個學生類:

test1.c:

#include <stdio.h>

//日期結構體
typedef struct 
{
  int year;//
  int month;//
  int day;//
}Date; 

//學生結構體 
typedef struct
{
  char sid[20];//學號
  char name[20];//姓名
  char gender;//性別
  Date birthday;//出生日期 
  char contact[50];//聯繫方式         
}Students;

void PrintStudentsInfo(Students s)
{
   printf("學號:%s\n",s.sid); 
   printf("姓名:%s\n",s.name);
   printf("性別:%c\n",s.gender);
   printf("出生日期:%d-%d-%d\n",s.birthday.year,s.birthday.month,s.birthday.day);
   printf("聯繫方式:%s\n",s.contact);      
}

int main()
{
  Students s1;//生成一個學生對象
  Date d1;
  d1.year = 1995;
  d1.month = 6;
  d1.day =30;
  strcpy(s1.sid,"S0001");
  strcpy(s1.name,"張三丰");
  strcpy(s1.contact,"西安市高新四路50號");
  s1.gender = 'M'; 
  s1.birthday = d1;
  PrintStudentsInfo(s1);
  getch();
  return 0;    
}

 運行效果:

2468cae2-d71a-4ad9-9f4b-4953f12bdf95

 

 二、用Java代碼定義一個學生類:

(1)Student.java:

 1 package test1;
 2 
 3 import java.text.SimpleDateFormat;
 4 import java.util.Date;
 5 
 6 /**
 7  * Created by smyhvae on 2015/8/12.
 8  */
 9 public class Student {
10     String num; //學號
11     String name; //姓名
12     char sex; //性別
13     Date birthday; //出生日期
14     String contact; //聯繫方式
15 
16     public String getNum() {
17         return num;
18     }
19 
20     public void setNum(String num) {
21         this.num = num;
22     }
23 
24     public String getName() {
25         return name;
26     }
27 
28     public void setName(String name) {
29         this.name = name;
30     }
31 
32     public char getSex() {
33         return sex;
34     }
35 
36     public void setSex(char sex) {
37         this.sex = sex;
38     }
39 
40     public Date getBirthday() {
41         return birthday;
42     }
43 
44     public void setBirthday(Date birthday) {
45         this.birthday = birthday;
46     }
47 
48     public String getContact() {
49         return contact;
50     }
51 
52     public void setContact(String contact) {
53         this.contact = contact;
54     }
55 
56     @Override
57     public String toString() {
58 
59         SimpleDateFormat sdf = new SimpleDateFormat("YYYY-mm-dd"); //將Date日期轉化爲String字符串打印出來
60 
61         return "Student{" +
62                 "num='" + num + '\'' +
63                 ", name='" + name + '\'' +
64                 ", sex=" + sex +
65                 ", birthday=" + sdf.format(birthday) +
66                 ", contact='" + contact + '\'' +
67                 '}';
68     }
69 
70 }

 

(2)JavaTest.java:(給學生類賦值並打印出來)

 1 package test1;
 2 
 3 import java.text.ParseException;
 4 import java.util.Calendar;
 5 import java.util.Date;
 6 
 7 /**
 8  * Created by smyhvae on 2015/8/12.
 9  */
10 public class JavaTest {
11 
12     public static void main(String[] args) throws ParseException {
13 
14         Student s = new Student();
15         s.setNum("111222");
16         s.setName("生命壹號");
17         s.setSex('男');  //這裏面賦值能夠用中文
18         s.setContact("smyhvae@163.com");
19 
20         Calendar calendar = Calendar.getInstance();
21         calendar.set(1991, 11, 28);
22         Date date = calendar.getTime();
23         s.setBirthday(date);
24 
25         System.out.println(s.toString());
26 
27     }
28 
29 } 

運行效果以下:

5379ace9-02fc-4aa3-84c0-fc3c16269257

  

5、算法的設計目標:

一、算法的設計目標:

(1)正確性:知足具體問題的解,基本目標。

(2)可讀性:有利於人去理解算法。

(3)健壯性:輸入非法數據,能適當作出處理,不產生莫名其妙的輸出。

(4)高效性:包括時間的高效性(時間複雜度)和空間的高效性(空間複雜度)。

二、算法性能指標:

(1)算法的時間效率也稱爲時間複雜度。

(2)算法的空間效率也稱爲空間複雜度。

(3)同一問題可用不一樣算法解決,而一個算法的質量優劣將影響到算法乃至程序的效率。算法分析的目的在於選擇合適算法和改進算法。一個算法的評價主要從時間複雜度和空間複雜度來考慮

(4)算法時間的高效性和空間的高效性一般是矛盾的。全部通常只會取一個平衡點。(這裏體現的是一種哲學思想,研究計算機,不就是研究時間和空間的概念嘛,魚與熊掌不可兼得哦)

(5)一般咱們假設程序運行在內存中,且內存容量足夠使用,因此更多的是討論時間複雜度

 

6、算法的時間複雜度:

算法的時間複雜度反映了算法執行的時間長短。度量一個算法在計算機上執行的時間一般有兩種方式:

  1.過後統計法:

  2.事前分析法:(經常使用)

    編寫算法使用的高級語言

    編程產生的機器語言代碼質量

    機器指令執行速度

    問題規模

注:算法的時間複雜度是由最深層嵌套語句的頻度決定的。

 

二、O()函數:

  表示算法的時間效率與算法所處理的數據元素個數n函數關係的最經常使用函數,即O()函數。

定義:

  通常狀況下,算法中基本操做重複執行的次數是問題規模n的某個函數,用T(n)表示,如有某個輔助函數f(n),使得當n趨近於無窮大時,T(n)/f(n)的極限值爲不等於零的常數,則稱f(n)是T(n)的同數量級函數。記做T(n)=O(f(n)),稱O(f(n)) 爲算法的漸進時間複雜度,簡稱時間複雜度。看下圖便知:

6c7a2288-b1a2-4b1a-9858-6c8103b3712d

25edf293-2825-401e-bda1-a6449cea6eca

狀況一:T(n)與問題規模n無關

當算法的時間複雜度T(n)與問題規模n無關時,此時算法的時間複雜度T(n)=O(1)。

 

狀況二:T(n)與問題規模n有關

例1:設數組a和b在前面部分已經賦值,求以下兩個n階矩陣相乘算法的時間複雜度:

for(i=0;i<n;i++)
 {
   for(j=0;j<n;j++)
   {
     c[i][j]=0;  //基本語句1
     for(k=0;k<n;k++)
     {
        c[i][j]=c[i][j]+a[i][k]*b[k][j];//基本語句2
     }
   }
 }

 上方代碼中:

557f59fb-97fd-4098-afa0-82dfcb2cf250

  

例2:設n爲以下算法處理的數據元素個數,求算法時間複雜度。代碼以下:

for(i=1;i<=n;i=i*2)
{
   System.out.println(i);
}

 分析:

01e98af6-e6c6-47f2-ab2d-d285baf389de

  

例3:分析冒泡排序算法的時間複雜度。代碼以下:

//冒泡排序算法
    public static void bubbleSort(int[] data) {

        if (data == null) {
            return;
        }

        for (int i = 0; i < data.length - 1; i++) {
            boolean flag = false;
for (int j = 0; j < data.length - 1 - i; j++) { if (data[j] > data[j + 1]) { int temp = data[j]; data[j] = data[j + 1]; data[j + 1] = temp; flag = true; } }
if (!flag) { return; } } }

 時間複雜度分析:

(1)最佳狀況下,冒泡排序算法只須要遍歷一次就能肯定數組已經排序好了,此時的時間複雜度爲O(n);

(2)最差狀況下,須要進行n-1次遍歷,則需進行n(n-1)/2次比較和記錄移動,此時冒泡排序算法的時間複雜度T(n)=O(n2)。

 

三、時間複雜度的大小關係:

如下六種計算算法時間的多項式是最經常使用的。其關係爲:

5defd8ca-9d0d-45f7-a85f-5b1aed4d8e04

指數時間的關係爲:

ba087e1f-ca41-498a-8b68-be21acc22dca

當n取很大的值時,指數時間算法和多項式時間算法在所需時間上很是懸殊。

小知識:

NP(nondeterministic polynomial)問題:是指算法複雜度難以用多項式表示的問題,算法複雜度一般是n的指數級,常規算法很難求解。

 

7、算法的空間複雜度:

空間複雜度是指算法在運行期間所須要的內存空間的數量級。記做:S(n)=O(f(n)),其中n爲問題的規模(或大小)。            

注:因爲大部分算法的空間複雜度問題並不嚴重,而且算法的空間複雜度分析方法和算法的時間複雜度分析方法基本相同,因此通常數據結構只討論算法的時間複雜度,不討論算法的空間複雜度。

代碼舉例:分析以下算法的空間複雜度

static void reserse(int[] a,int[] b)
{
   int n= a.length;
   for(int i=0;i<n;i++)
   {
      b[i]=a[n-1-i];
   }
} 

上方代碼中,當程序調用reserse(a,b)函數時,要分配的內存空間包括:引用a,引用b,局部變量n和局部變量i;

所以f(n)=c;其中c爲常量。因此該算法的空間複雜度S(n)=O(1)。

 

8、總結:

算法的時間複雜度和兩個因素有關:算法中的最大嵌套循環層數;最大嵌套循環結構中每次循環的次數。

通常來講,具備多項式時間複雜度的算法是能夠接受的;具備指數(不是對數)時間複雜度的算法,只有當n足夠小時纔可使用。通常效率較好的算法要控制在O(N)或者O(log2 N)

 

手有玫瑰,贈人餘香。支付寶掃一掃吧:

相關文章
相關標籤/搜索