1. 程式人生 > >《傳智播客-資料結構》01 資料結構基本概念 2018/10/14

《傳智播客-資料結構》01 資料結構基本概念 2018/10/14

1.資料結構概念

1.1 資料結構的起源

資料結構主要用於研究非數值計算程式問題中的操作物件以及它們之間的關係,不是研究複雜的演算法

1.2基本概念

資料--程式的操作物件,用於描述客觀事物(int  a ,int b)

資料的特點: 1、可輸入到計算機內  2、可被計算機程式處理

資料是一個抽象的概念,將其分類後,得到程式設計語言中的型別。如,int float  char等等

資料元素:組成資料的基本單位

資料項:一個數據元素由若干資料組成

資料物件:性質相同的元素的集合

//來自結構體課堂程式碼
//宣告一個結構體型別
struct _MyTeacher	//一種資料型別
{
	char	name[32];
	char	tile[32];
	int 	age;
	char 	addr[128];
};

int main()
{
	struct _MyTeacher	t1;		//資料元素
	struct _MyTeacher 	tArray[30];		//資料物件
	memset(&t1,0,sizeof(t1));			
	
	strcpy(t1.name,"name");		//資料項
	strcpy(t1.addr,"addr");		//資料項
	strcpy(t1.title,"addr");	//資料項
	t1.age = 1;
}

資料結構指資料物件中資料元素之間的關係  

1.3資料的邏輯結構

依據資料元素之間的關係,分為四種基本資料結構

1、集合--資料元素之間除“同屬一個集合外”,無其他關係

2、線性結構--一個對一個,如,線性表,棧,佇列

3、樹形結構--一個對多個,如樹

4、圖形結構--多個對多個,如圖

1.4資料的物理結構

即儲存結構,是資料的物理結構在計算機儲存器內的表示(映像).依賴於計算機

主要分為:順序、鏈式、索引、雜湊

順序儲存--藉助元素在儲存器中的相對位置來表示,

鏈式儲存--藉助指示元素儲存地址的指標來表示資料

演算法設計-------邏輯結構

演算法實現--------物理結構

1.5資料的運算

插入、刪除、修改、查詢、排序

2 演算法

2.1基本概念

對特定問題求解步驟的描述

在計算機中國表現為指令的有限序列

演算法是獨立存在的一種解決問題的方法和思想

2.2演算法和資料結構的區別

資料結構知識靜態的描述了資料元素之間的關係

高效的程式需要在資料結構的基礎上設計和選擇演算法

---程式= 資料結構+演算法

2.3演算法的特性:

輸入:具有0個或者多個輸入

輸出:至少有一個或多個輸出

有窮性:演算法在有限的步驟之後會自動結束而不會無限迴圈

確定性:演算法的每一步都有確定的含義,不會出現二義性。

可行性:演算法的每一步都是可行的。

2.4演算法效率的質量

1、事後統計法

比較不同演算法對同一組輸入資料的執行處理時間

事前分析估算

//演算法最終編譯成具體的計算機指令
//每一個指令,在具體的計算機上執行速度固定
//通過具體的n的步驟,就可以推匯出演算法的複雜度
long sum1(int n)
{
    long ret = 0;                         
    int* array = (int*)malloc(n * sizeof(int)); 
    int i = 0;  
    
    for(i=0; i<n; i++)   
    {
        array[i] = i + 1;
    }
    
    for(i=0; i<n; i++) 
    {
        ret += array[i];
    }
    
    free(array); 
    
    return ret; 
}

long sum2(int n)
{
    long ret = 0;
    int i = 0;
    
    for(i=1; i<=n; i++)
    {
        ret += i;
    }
    
    return ret;
}

long sum3(int n)
{
    long ret = 0;
    
    if( n > 0 )
    {
        ret = (1 + n) * n / 2; 
    }
    
    return ret;
}

int main()
{
    printf("%d\n", sum1(100));
    printf("%d\n", sum2(100));
    printf("%d\n", sum3(100));
    
    return 0;
}
int func(int a[], int len)
{
    int i = 0;
    int j = 0;
    int s = 0;
    
    for(i=0; i<len; i++) n
    {
        for(j=0; j<len; j++) n
        {
            s += i*j;  //n*n
        }
    }
    return s; 
}

說明:

1:判斷一個演算法的效率時,往往只需要關注運算元量的最高次項,其它次要項和常數項可以忽略。

2:在沒有特殊說明時,我們所分析的演算法的時間複雜度都是指最壞時間複雜度。

2、大O表示法

演算法效率嚴重依賴於操作(Operation)數量

在判斷時首先關注運算元量的最高次項

運算元量的估算可以作為時間複雜度的估算

3、演算法的空間複雜度

演算法的空間複雜度通過計算演算法的儲存空間實現

S(n) = O(f(n))

其中,n為問題規模,f(n))為在問題規模為n時所佔用儲存空間的函式

大O表示法同樣適用於演算法的空間複雜度

當演算法執行時所需要的空間是常數時,空間複雜度為O(1)

練習2:時間換空間 
/*
    問題: 
    在一個由自然數1-1000中某些數字所組成的陣列中,每個數字可能出現零次或者多次。
    設計一個演算法,找出出現次數最多的數字。
*/
方法1:
   排序,然後找出出現次數最多的數字

方法2:
void search(int a[], int len)
{
    int sp[1000] = {0};
    int i = 0;
    int max = 0;
    
    for(i=0; i<len; i++)
    {
        int index = a[i] - 1;
        
        sp[index]++;
    }
    
    for(i=0; i<1000; i++)
    {
        if( max < sp[i] )
        {
            max = sp[i];
        }
    }
    
    for(i=0; i<1000; i++)
    {
        if( max == sp[i] )
        {
            printf("%d\n", i+1);
        }
    }
}

int main()
{
    int array[] = {1, 1, 3, 4, 5, 6, 6, 6, 2, 3};
    
    search(array, sizeof(array)/sizeof(*array));
    
    return 0;
}

把每個數字出現的次數的中間結果,快取下來;在快取的結果中求最大值。