日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

郝斌——数据结构笔记(数组、链表、栈、队列)(递归)

發(fā)布時間:2023/12/31 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 郝斌——数据结构笔记(数组、链表、栈、队列)(递归) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

  • 一、預備知識
    • 1、預備知識
      • (1)數(shù)據(jù)結(jié)構(gòu)概述
    • 2、衡量算法的標準
    • 3、數(shù)據(jù)結(jié)構(gòu)的地位
    • 4、指針
      • (1)基本類型的指針
      • (2)數(shù)組和指針
    • 5、結(jié)構(gòu)體的使用
    • 6、動態(tài)內(nèi)存的分配
      • (1)舉例:動態(tài)構(gòu)造一個int型數(shù)組
      • (2)跨函數(shù)使用內(nèi)存
    • 7、typedef 的用法
  • 模塊一:線性結(jié)構(gòu)
    • 1、連續(xù)存儲數(shù)組
      • (1)init_arr
      • (2)show_arr
      • (3)append_arr
      • (4)insert_arr
      • (5)delete_arr
      • (6)inversion_arr
      • (7)sort_arr
    • 2、離散存儲鏈表
      • (1)專業(yè)術(shù)語
      • (2)節(jié)點的數(shù)據(jù)類型,該如何表示
      • (3)鏈表的分類
      • (4)鏈表的偽算法
      • (5)基本算法實現(xiàn)
        • (1)create_list
        • (2)traverse_list
        • (3)is_empty
        • (4)length_list
        • (5)insert_list
        • (6)delete_list
        • (7)sort_list
        • 補充泛型的初步定義:
    • 3、線性結(jié)構(gòu)的應用 —— 棧
      • (1)序言
      • (2)棧的算法實現(xiàn)
        • (1)init
        • (2)push
        • (3)traverse
        • (4)pop
        • (5)clear
      • (3)棧的應用
    • 4、線性結(jié)構(gòu)的應用—— 隊列
      • (1)序言
      • (2)靜態(tài)隊列的分析:
      • (3)循環(huán)隊列程序演示
        • (1)init
        • (2)en_queue
        • (3)full_queue
        • (4)traverse_queue
        • (5)out_queue
        • (6)empty_queue
      • (4)隊列的具體的應用
  • 遞歸專題
    • 1、前景知識
    • 2、應用舉例
      • (1)求階乘
      • (2)求 1+2+3+4+....+100
    • 3、對遞歸的理解
      • (1)函數(shù)調(diào)用:
      • (2)函數(shù)調(diào)用,棧的使用
      • (3)遞歸調(diào)用,必須滿足的3個條件
      • (4)循環(huán)的遞歸的關(guān)系
      • (5)漢諾塔
    • 4、遞歸的應用

學玩數(shù)據(jù)結(jié)構(gòu)要達到的目的:
(1)對數(shù)據(jù)結(jié)構(gòu)要有一個基本的了解。
(2)要熟練 掌握鏈表的操作
(3)偽算法要能看懂(偽算法:只是邏輯,沒有代碼實現(xiàn))

一、預備知識

使用教材:嚴蔚敏,吳偉民編寫的《數(shù)據(jù)結(jié)構(gòu)》
但是書中的算法都是偽算法(不是程序),都是解題的思路
具體的程序由高一凡主編的書里面有。
黃國瑜寫的數(shù)據(jù)結(jié)構(gòu)也可以。

模塊一: 線性結(jié)構(gòu)

  • 連續(xù)存儲(數(shù)組
    優(yōu)點:存取速度很快,可以直接找到某一個元素
    缺點:
    (1)插入刪除元素比較慢(后面的元素都得移動)
    (2)需要大片的內(nèi)存
    (3)事先知道數(shù)組的長度(防止內(nèi)存污染)

  • 離散存儲(鏈表
    優(yōu)點:
    (1)插入刪除元素比較方便(只需要切換指針域即可)
    (2)并不需要大片的內(nèi)存
    缺點:存取速度比較慢

  • 線性結(jié)構(gòu)的兩種常用應用之一 (

  • 線性結(jié)構(gòu)的兩種常用應用之一 (隊列

  • 專題:遞歸
    (1)1+2+3+4+5+… 100 的和
    (2)求階乘
    (3)漢諾塔
    (4)走迷宮

模塊二:非線性結(jié)構(gòu)

模塊三:查找和排序

  • 折半查找
  • 排序:冒泡、插入、選擇、快速、歸并

1、預備知識

(1)數(shù)據(jù)結(jié)構(gòu)概述

定義:
1、我們?nèi)绾伟熏F(xiàn)實當中,大量而復雜的問題以,特定的數(shù)據(jù)類型特定的存儲結(jié)構(gòu),保存到內(nèi)存當中。

2、在此基礎上,為實現(xiàn)某個功能(比如查找某個元素、刪除某個元素、對所有元素進行排序),而執(zhí)行的相應操作,這個相應的操作叫做算法

舉例:如何保存一個班級學生的信息?

(1)少數(shù)較少的時候,使用數(shù)組就可以。(需要內(nèi)存是連續(xù)的)
(2)但是保存1000 個學生信息,就沒有這么大的連續(xù)空間,可以使用鏈表實現(xiàn)。(使用鏈表,可以將其他零散的內(nèi)存利用起來)

(3)如保存人事單,如果使用鏈表則不知道他們之間的關(guān)系誰是領導,這種結(jié)構(gòu)需要使用樹結(jié)構(gòu)。(樹的結(jié)構(gòu):就可以知道誰是領導,誰是下屬)

(4)再如交通圖,幾個站點之間修路,則需要使用圖結(jié)構(gòu)實現(xiàn)。

總結(jié):
數(shù)據(jù)結(jié)構(gòu):解決數(shù)據(jù)如何存儲的問題。(個體和個體的關(guān)系)
算法:如何對已經(jīng)存儲的數(shù)據(jù),進行操作

2、衡量算法的標準

1、時間復雜度:大概程序要執(zhí)行的次數(shù)、而非執(zhí)行的時間。(因為硬件不同)

2、空間復雜度:算法執(zhí)行過程中,大概所占用的最大內(nèi)存

3、難易程度:不能只有自己一個看懂

4、健壯性:不能給一個非法立即數(shù)就掛掉了。

3、數(shù)據(jù)結(jié)構(gòu)的地位

數(shù)據(jù)結(jié)構(gòu)是軟件中最核心的課程

程序 = 數(shù)據(jù)的存儲 + 數(shù)據(jù)的操作 + 可以被計算執(zhí)行的語言。

4、指針

(1)內(nèi)存是 cpu 能夠直接訪問的,唯一的存儲器

(2)通過地址線,來確定,對哪塊內(nèi)存來進行存儲。(32位——0 – 4G-1)

(3)通過控制線,來確定,對內(nèi)存是 讀取還是 寫入。

(4)通過數(shù)據(jù)線,來確定,傳輸什么數(shù)據(jù)。

總結(jié):
(1)地址:內(nèi)存單元的編號, 0000 0000 – FFFF FFFF, 從0 開始的非負整數(shù)。

(2)指針:指針就是地址,地址就是指針。是一個操作受限的非負整數(shù)。

(3)指針變量:是存放,內(nèi)存單元地址(編號),的單元。

(1)基本類型的指針

int *p;

p : 是一個變量的名字
int * :表示 p 只能存放整形變量的地址

必須理解,只能存放,這個概念。

int * p; char a = 'A'; p = &a; //error:&a 不是整形變量的地址 p = 10//error:10 是一個整數(shù),不是一個地址

(2)數(shù)組和指針

int a[5] = {1,2,3,4,5};

數(shù)組名的理解:
(1)一維數(shù)組名:它是一個,指針常量
(2)一維數(shù)組名:它里面存放的是,第一個元素的地址
(3)一維數(shù)組名:指向,數(shù)組當中的第一個元素。

下標的理解:

a[3] <=====> *(a+3)3[a] <=====> *(a+3)

5、結(jié)構(gòu)體的使用

(1)為什么會出現(xiàn)結(jié)構(gòu)體?
為了表示一些復雜的數(shù)據(jù)類型,而單個基本類型無法滿足需要。

(2) 什么是結(jié)構(gòu)體?
用戶根據(jù)實際需要,自己定義的復合數(shù)據(jù)類型。

分號不能省略,分號表示結(jié)構(gòu)體定義結(jié)束

struct Student{ int aga; char address; char sex; }; //分號不能省略,分號表示結(jié)構(gòu)體定義結(jié)束
  • 定義了一個,新的數(shù)據(jù)類型。(類似于 int )
  • 只是單純的定義了一個類型,而不定義一個變量,也就是說并不分配內(nèi)存
  • 這個數(shù)據(jù)類型的名字: struct Student

(3)如何使用結(jié)構(gòu)體

兩種方式:struct Student st = {1000, "zhangsan", 20};struct Student * pst = &st;1.st.sid 2.pst->sidpst所指向的結(jié)構(gòu)體變量中的sid這個成員

注意事項

  • 結(jié)構(gòu)體變量不能加減乘除,但是可以相互賦值
  • 普通結(jié)構(gòu)體變量 和 結(jié)構(gòu)體指針變量,作為函數(shù)參數(shù)傳參的問題
#include <stdio.h> #include <string.h>struct Mystruct {int id;char name[200];int age; }; void fcun(struct Mysturct s1) // 輸入型參數(shù),不會修改本身的值 { printf("%d,%s,%d \n", s1.id,s1.name,s1.age); } void func1(struct Mysturct *ps1) // 輸出型參數(shù),會修改實參的值 {*ps1.s1 = 10086;strcpy(ps1->name,"zhangsan");ps1->age = 20; }int main(void) {struct Mysturct s1;func1(&s1);func(s1); }

(1)當結(jié)構(gòu)體變量,變?yōu)楹瘮?shù)參數(shù)時候:

void fcun(struct Mysturct s1) // 輸入型參數(shù),不會修改本身的值 { printf("%d,%s,%d \n", s1.id,s1.name,s1.age); }

這樣傳參:會發(fā)生結(jié)構(gòu)體的賦值,整個結(jié)構(gòu)體單元都會被拷貝。
這種方法:耗用內(nèi)存、耗費時間,不推薦。(發(fā)送了 200多個字節(jié))

解決辦法:結(jié)構(gòu)體指針傳參

void fcun(struct Mysturct *s1) // 輸入型參數(shù),不會修改本身的值 { printf("%d,%s,%d \n", s1->id,s1->name,s1->age); }

這樣傳參:只傳送了 4 個字節(jié)。

6、動態(tài)內(nèi)存的分配

怎么區(qū)分動態(tài)內(nèi)存和靜態(tài)內(nèi)存?

只要使用了 malloc 函數(shù)就是動態(tài)的。
沒使用,就是靜態(tài)的。

(1)舉例:動態(tài)構(gòu)造一個int型數(shù)組

char a[5] = {1,2,3,4,5};

這個數(shù)組的空間大小,在運行當中是不可以改變的,只能重新編寫。

int len; printf("請輸入你需要的數(shù)組的長度 len = "); scanf("%d",len); int *pArr = (int *) malloc(sizeof(int) * len);*pArr = 4; // 類似于 a[0] = 4 pArr[1] = 5; // pArr[1] <=====> *(pArr + 1)free(pArr); // 釋放這個內(nèi)存空間

這個數(shù)組的空間大小,在運行當中,取絕于用戶的輸入,所以是動態(tài)的。

(1)malloc 函數(shù)的形參:是一個 int 類型的整數(shù),表示申請多少個字節(jié)大小的內(nèi)存空間。
(sizeof 返回值是一個整數(shù),int 占用4個字節(jié))

(2)malloc函數(shù)的功能是請求系統(tǒng)len個字節(jié)的內(nèi)存空間,如果請求分配成功,則返回第一個字節(jié)的地址,如果分配不成功,則返回NULL.

第一個字節(jié)地址:它并沒有實際的含義,因為我們根據(jù)這個地址,可以把 8 個字節(jié)當一個變量,也可以把4個字節(jié)當一個變量

(3)(int *) 強制轉(zhuǎn)換:就是根據(jù)這個地址,把4個字節(jié)當作一個變量。

(4)malloc 申請的空間使用

*pArr = 4; // 類似于 a[0] = 4 pArr[1] = 5; // pArr[1] <=====> *(pArr + 1)

可以當作一個普通的數(shù)組來使用。

(2)跨函數(shù)使用內(nèi)存

通過調(diào)用 fun ,使main 函數(shù)當中的指針變量 p 指向一個合法的變量單元。

void fun(int *q) {int s;q = &s; }int main(void) {int *p;fun(p); }

不可以:因為這是一個 值傳遞,調(diào)用完函數(shù),實參p 的值根本沒有改變

void fun(int **q) {int s;*q = &s; }int main(void) {int *p;fun(&p); }

不可以:
(1)雖然變成了地址傳遞,最終 p 的值也發(fā)生了改變。
(2)但是 s 變量的內(nèi)存,在fun 執(zhí)行完畢之后,就銷毀了。

void fun(int *q) {q = (int *) malloc(4); }int main(void) {int *p;fun(p); }

不可以:因為這是一個 值傳遞,調(diào)用完函數(shù),實參p 的值根本沒有改變

void fun(int **q) {*q = (int *) malloc(4); }int main(void) {int *p;fun(&p); }

可以訪問:因為malloc 函數(shù)申請的內(nèi)存,只有 free 函數(shù)才能釋放。

使用案例:

#include <stdio.h> #include <malloc.h>struct Student {int id;int age; };struct Student * CreatStudent(); // 返回值使 struct Student * 類型 {return (struct Student *) malloc(sizeof(struct Student)); } void ShowStudent(struct Student *ps1) {printf("%d, %d\n", ps1->id, ps1->age); }int main() { struct Student *ps1; //申請了 4 個字節(jié)的內(nèi)存空間 ps1 = CreatStudent(); // 又申請了 8 個字節(jié)(1個結(jié)構(gòu)體變量)的空間 ShowStudent(ps1); // 輸入型參數(shù) return 0; }

7、typedef 的用法

我們自己構(gòu)建的數(shù)據(jù)類型,struct Mystruct 的名字太長用起來不方便

typedef int zhangsan int i = 0; <======> zhangsan i = 0; typedef struct Student {int sid;char name[20]'int age; }ST; // typedef 給 struct Student 新起了一個名字叫做 STstruct Student st; <=======> ST st; struct Student *pst; <=======> ST *pst; typedef struct Student {int sid;char name[20]'int age; }* PST; // typedef 給 struct Student * 新起了一個名字叫做 PST struct Student *pst; <=======> PST pst; typedef struct Student {int sid;char name[20]'int age; }* PSTU,STU; // typedef 給 struct Student * 新起了一個名字叫做 PSTU // 給 struct Student 新起了一個名字叫做 STU struct Student *pst; <=======> PSTU pst; struct Student st <=======> STU st;

模塊一:線性結(jié)構(gòu)

數(shù)據(jù)結(jié)構(gòu) = 個體的存儲 + 個體的關(guān)系存儲
算法 = 對存儲數(shù)據(jù)的操作(增加、刪除、遍歷等等)

別人問:什么是線性結(jié)構(gòu)?
把所有的結(jié)點用一根直線穿起來

1、連續(xù)存儲數(shù)組

int a[10]; int *pArr = (int *)malloc(len);

自己定義一個數(shù)據(jù)類型,并且為它添加方法。

#include <stdio.h> #include <malloc.h> //定義一個數(shù)據(jù)類型,里面又三個變量 struct Arr {int *pBase; // 存放數(shù)組第一個元素的地址int len; // 數(shù)組所能容納的最大個數(shù)int cnt;// 當前數(shù)組的元素個數(shù) } // 定義一些算法 void init_arr(); // 初始化整個數(shù)組 bool append_arr(); //在數(shù)組最后,追加一個元素 bool insert_arr(); // 在數(shù)組當中插入一個元素 bool delete_arr(); // 刪除一個數(shù)組元素 bool get_arr(); bool is_empty(); // 判斷是否為空 boll is_full(); // 判斷是否為滿void sort_arr(); // 排序整個數(shù)組 void show_arr(); // 輸出數(shù)組 void inversion_arr(); //導致整個數(shù)組int main(void) {struct Arr arr;init_arr(&arr,6);shouw_arr(&arr);return 0; }void init_arr(struct Arry *pArr , int length) { pArr -> pBase = (int *) malloc(sizeof(struct Arry) * length); if(NULL == pArr->pBase){printf("malloc error");exit(-1); // 終止整個程序} else{pArr -> len = length;pArr -> cnt = 0;}return; }

(1)init_arr

我們希望,一調(diào)用 init_arr 函數(shù), arr 當中的 pBase 指向一塊連續(xù)內(nèi)存。len 表示這個內(nèi)存的大小,cnt 有效元素的個數(shù)。

分析: 1、需不需要返回值 2、需不需要參數(shù):肯定需要,沒有的話,不知道操作誰(1)輸入型參數(shù)?(2)輸出型參數(shù)?struct Arr arr; init_arr(arr); void init_arr(strcut Arr array) // 傳值方式,根本不會改變實參的內(nèi)容 {array.len = 99; }struct Arr arr; init_arr(&arr); // 傳入地址 void init_arr(strcut Arr *parr) // 傳址方式,可以改變實參內(nèi)容 {(*parr).len = 99; }void init_arr(struct Arry *pArr , int length) { pArr -> pBase = (int *) malloc(sizeof(struct Arry) * length); if(NULL == pArr->pBase){printf("malloc error");exit(-1); // 終止整個程序} else{pArr -> len = length;pArr -> cnt = 0;}return; }

(2)show_arr

輸出這個數(shù)組
傳入指針:只傳遞 4 個字節(jié)的內(nèi)容

void show_arr(struct Arry *pArr) // 輸出數(shù)組, {if(數(shù)組為空)提示用戶數(shù)組為空else輸出數(shù)組有效內(nèi)容 }bool is_empty(struct Arry *pArr) {if(0 == pArr -> cnt)return ture;elsereturn flase; }要注意:pArr 是一個結(jié)構(gòu)體變量的地址 void show_arr(struct Arry *pArr) // 輸出數(shù)組, {if(is_empty(pArr))printf("數(shù)組為空!\n");elsefor(int i = 0; i < pArr->cnt , i++){printf("%d\n",pArr->pBase[i]);} }

(3)append_arr

bool append_arr(struct Arry *pArr, int val) {if(數(shù)組滿了)提示用戶數(shù)組滿了else追加 }bool is_full(struct Arry *pArr) {if(pArr->cnt == pArr->len)return ture;elsereturn flase; }bool append_arr(struct Arry *pArr, int val) {if(is_full(pArr)){printf("數(shù)組已滿\n");return flase;}elsepArr->pBase[pArr->cnt] = val;(pArr->cnt)++;return ture; }

(4)insert_arr

思考函數(shù)要實現(xiàn)的功能:
向指定位置插入一個數(shù)字。
所以需要傳入的參數(shù):
1、結(jié)構(gòu)體(數(shù)組、數(shù)組大小、當前元素個數(shù))
2、準備插入的位置
3、要插入的值

// pos從1開始,假設pos = 3, val = 55; 則 a[2] = 55; bool insert_arr(struct Arry *pArr, int pos,int val) {int i = 0;if(is_full(pArr)) // 如果滿了return flase;if(pos<1 || pos > pArr->cnt-1) //如果元素不夠:一共有 3 個元素,就不可以在第 5 個位置插入return flase;// 先進行后移for(i = cnt-1; i>=pos-1; i--) // 這個循環(huán),一步一步去試數(shù)字然后往出寫{pArr->pBase[i+1] = pArr->pBase[i]} // 再進行插入pArr->pBase[pos-1] = val;(pArr->cnt)++; }

(5)delete_arr

思考函數(shù)要實現(xiàn)的功能:
向指定位置刪除一個函數(shù)、并且返回成功、還是返回失敗?并且想返回被刪除的值?
所以需要傳入的參數(shù):
1、結(jié)構(gòu)體(數(shù)組、數(shù)組大小、當前元素個數(shù))
2、準備刪除的位置
3、輸出型參數(shù) int *pVal (從而實現(xiàn)多個返回值)

主函數(shù)調(diào)用: int val; // 定義一個變量來接收刪除的數(shù)字 struct Arr arr;delete(&arr,1,&val);bool delete(struct Arry *pArr, int pos, int *pVal) {int i = 0;if( is_empty(pArr) )return flase;if(pos<1 || pos > pArr->cnt) // 要刪除,必須有這個值return flase;// 先拿出*pVal = pArr->pBase[pos-1];// 再移動for(i = pos; i<cnt ; i++){pArr->pBase[i-1] = pArr->pBase[i];(pArr->cnt)--;}return ture; }

(6)inversion_arr

函數(shù)功能:倒置
最后一個換到第一個

void inversion_arr(struct Arry *pArr) {int i = 0; //第一個元素int j = (pArr->cnt)- 1// 最后一個元素int tmp = 0; while(i<j){tmp = pArr->pBase[i];pArr->pBase[i] = pArr->pBase[j];pArr->pBase[j] = tmp;} return 0; }

(7)sort_arr

void sort_arr(struct Arry *pArr) {int i, j = 0;int tmp = 0;for(i=0; j < pArr->cnt-1; ++i) // cnt-1 說明最后一個不用比較{for(j = i+1 ; j <pArr->cnt; ++j){if(pArr->pBase[i] > pArr->pBase[j]) // 把小的換到前面來{tmp = pArr->pBase[i];pArr->pBase[i] = pArr->pBase[j];pArr->pBase[j] = tmp;} }}}

2、離散存儲鏈表

鏈表的重要性:是我們學習數(shù)據(jù)結(jié)構(gòu)的基礎,
如下面的樹(一個結(jié)點指向下面多個結(jié)點

圖(任何一個結(jié)點可以保存其他結(jié)點的地址

(1)專業(yè)術(shù)語

定義

(1)n個節(jié)點離散分配
(2)彼此通過指針相連接,上一結(jié)點保存了下一個結(jié)點的地址
(3)每個節(jié)點只有一個前驅(qū)節(jié)點,一個后續(xù)節(jié)點。首節(jié)點沒有前驅(qū)節(jié)點,尾結(jié)點沒有后續(xù)節(jié)點。
(樹下面可以有很多節(jié)點)

專業(yè)術(shù)語:

首節(jié)點:第一個有效結(jié)點
尾結(jié)點:最后一個有效結(jié)點

頭結(jié)點:
(1)第一個有效結(jié)點,之前的結(jié)點
(2)頭結(jié)點,不存放有效數(shù)據(jù)
(3)加頭結(jié)點的目的是可以方便我們對鏈表的操作
(4)頭結(jié)點與其他結(jié)點,數(shù)據(jù)類型完全一樣

頭指針:第一個節(jié)點的地址
指向頭結(jié)點的指針變量(可能不對,是指向第一個有效結(jié)點的指針)

尾指針:最后一個節(jié)點的地址
指向尾結(jié)點的指針變量。

如果我們希望,通過函數(shù)來對鏈表進行處理,我們至少需要接受鏈表的幾個參數(shù)

數(shù)組:(3個參數(shù))首地址、長度、當前元素個數(shù)。

鏈表:(1個參數(shù))首地址(頭指針)
注:
(1)頭節(jié)點的數(shù)據(jù)結(jié)構(gòu),和其他的節(jié)點一樣。
(2)所以我們知道 頭指針,可以一個一個推算出下面節(jié)點的信息。

(2)節(jié)點的數(shù)據(jù)類型,該如何表示

每一個節(jié)點,都是一個數(shù)據(jù)類型
每一個節(jié)點當中,應該包含什么?應該有幾個成員?

  • 有效數(shù)據(jù)
  • 指針(地址):指向下一個節(jié)點。

問題:
(1)通過指針,我們要找到后面一個節(jié)點,而不是僅僅是首地址。

int *p = (int *)0x10002000; *p = 2; // 這樣的解引用,是將整數(shù) 2 ,存放到了 0x10002000 地址開頭的四個字節(jié)當中。char *p = (char *)0x10002000; *p = 2; // 這樣的解引用,是將整數(shù) 2 ,存放到了 0x10002000 地址開頭的 1 個字節(jié)當中。

我們每個節(jié)點的數(shù)據(jù)類型一樣
所以我們指針,相當于指向了和自己數(shù)據(jù)類型一樣的變量。

struct Node {int data; // 數(shù)據(jù)域(本身可以特別復雜)struct Node *pNext; // 指針域 }typedef struct Node {int data; // 數(shù)據(jù)域(本身可以特別復雜)struct Node *pNext; // 指針域 }NODE, *PNODE;

(3)鏈表的分類

  • 單鏈表

  • 雙鏈表(每一個節(jié)點有兩個指針域

  • 循環(huán)鏈表 能通過一個節(jié)點,找到任何一個節(jié)點

  • 非循環(huán)鏈表

(4)鏈表的偽算法

遍歷(找到節(jié)點,之后就可以,增加、刪除、改變、等等)
查找
清空
銷毀
求長度
排序
刪除結(jié)點
插入節(jié)點

插入非循環(huán)節(jié)點的偽算法

把 q 指向的節(jié)點,插入 p 指向節(jié)點的后面

注意:指針和結(jié)構(gòu)體的知識:
(1)指針 p :本身并沒有指針域, p 指向的結(jié)構(gòu)體才有指針域

p -> pNext ; // p 指向結(jié)構(gòu)體,這樣調(diào)用該結(jié)構(gòu)體當中的成員

(2)實現(xiàn)的效果:p中的指針域,指向q。 q當中指針域指向下一個節(jié)點

p -> pNext = q; // p指向的結(jié)構(gòu)體當中的指針域,指向q q -> pNext = // 發(fā)現(xiàn)已經(jīng)丟失了一下個節(jié)點的地址 r = p -> pNext; // 先將下一個地址,存起來 p -> pNext = q; q -> pNext = r; q -> pNext = p -> pNext; // 先將 q 的指針域,指向下一個節(jié)點 p -> pNext = q;

刪除肺循環(huán)節(jié)點的偽算法

問題:導致內(nèi)存泄漏(找不到第2個節(jié)點的地址,所以無法釋放)

p -> pNext = p -> pNext -> pNext ; free(p -> pNext) ; //錯誤:p -> pNext 已經(jīng)發(fā)生改變

解決:

r = p -> pNext; // 先將第二個節(jié)點地址保存 p -> pNext = p -> pNext -> pNext ; free(r); // 然后再釋放

(5)基本算法實現(xiàn)

#include <stdio.h> #include <malloc.h>typedef struct Node {int data; // 數(shù)據(jù)域struct Node *pNode; // 指針域 }NODE, *PNODE;int main(void) {//跨函數(shù)使用內(nèi)存(動態(tài)內(nèi)存)PNODE pHead = NULL;pHead = create_list(); // 創(chuàng)建一個非循環(huán)單鏈表,并將該鏈表的頭節(jié)點地址賦值給 pHead return 0; }

(1)create_list

1、返回值:(是一個地址,頭節(jié)點地址) PNODE
2、參數(shù):不需要

流程:

1、首先生成一個頭節(jié)點
2、由用戶決定生成的節(jié)點個數(shù)
3、創(chuàng)建這些節(jié)點

不循環(huán)生成節(jié)點:非常麻煩,想要申請100個,就得寫100次。

//獲取用戶信息 printf("請輸入第 1 個節(jié)點的值: val= "); scanf("%d",&val); //生成第一個節(jié)點的地址為 pNew PNODE pNew1 = (PNODE)malloc(sizeof(NODE)); //將用戶信息存放 pNew1 -> data = val; //將這個節(jié)點的首地址,掛到上一個節(jié)點指針域 pHead -> pNext = pNew1; // 每次創(chuàng)建,將尾結(jié)點的指針域指向 NUll pNew1 -> pNext = NULL;// 第二個節(jié)點 //獲取用戶信息 printf("請輸入第 2 個節(jié)點的值: val= "); scanf("%d",&val); //生成第二個節(jié)點的地址為 pNew2 PNODE pNew2 = (PNODE)malloc(sizeof(NODE)); //將用戶信息存放 pNew2 -> data = val; //將這個節(jié)點的首地址,掛到上一個節(jié)點指針域 pNew1 -> pNext = pNew2 ; // 每次創(chuàng)建,將尾結(jié)點的指針域指向 NUll pNew2 -> pNext = NULL;

循環(huán)生成節(jié)點:

for (i = 0; i < len; i++) {//獲取用戶信息 printf("請輸入第 1 個節(jié)點的值: val= "); scanf("%d",&val); //生成第一個節(jié)點的地址為 pNew PNODE pNew = (PNODE)malloc(sizeof(NODE)); //將用戶信息存放 pNew -> data = val; //將這個節(jié)點的首地址,掛到上一個節(jié)點指針域 pHead -> pNext = pNew; // 每次創(chuàng)建,將尾結(jié)點的指針域指向 NUll pNew -> pNext = NULL; }

出現(xiàn)的問題:只有第一次可以創(chuàng)建成功,后面都失敗

解決辦法:自己構(gòu)造一個,多余的指針,讓這個指針始終指向尾結(jié)點

for (i = 0; i < len; i++) {//獲取用戶信息 printf("請輸入第 1 個節(jié)點的值: val= "); scanf("%d",&val); //生成第一個節(jié)點的地址為 pNew PNODE pNew = (PNODE)malloc(sizeof(NODE)); //將用戶信息存放 pNew -> data = val; //將這個節(jié)點的首地址,掛到上一個節(jié)點指針域 pTail -> pNext = pNew; // 每次創(chuàng)建,將尾結(jié)點的指針域指向 NUll pNew -> pNext = NULL; // 將pTail 后移 pTail = pNew; }

整體的創(chuàng)建實現(xiàn)

PNODE create_list() {int len = 0;int i = 0;int val = 0;//生成一個頭節(jié)點PNODE pHead = (PNODE) malloc(sizeof(NODE));if(NULL = pHead){printf("分配失敗\n");exit(-1);}PNODE pTail = pHead ;pHead -> pNext = NULL; // 尾結(jié)點的指針域永遠為NULLprintf("請輸入您需要生成的鏈表節(jié)點個數(shù):len = ");scanf("%d",len);//數(shù)組的內(nèi)存是連續(xù)的,所以可以直接 malloc//鏈表的內(nèi)存是離散的,所以需要一個循環(huán)for (i = 0; i < len; i++){//獲取用戶信息printf("請輸入第 1 個節(jié)點的值: val= ");scanf("%d",&val);//生成第一個節(jié)點的地址為 pNew PNODE pNew = (PNODE)malloc(sizeof(NODE));//將用戶信息存放pNew -> data = val;//將這個節(jié)點的首地址,掛到上一個節(jié)點指針域pTail -> pNext = pNew;// 每次創(chuàng)建,將尾結(jié)點的指針域指向 NUllpNew -> pNext = NULL;// 將pTail 后移pTail = pNew;}return pHead; // 返回頭指針 }

(2)traverse_list

1、返回值:不需要
2、參數(shù):必須要,指定對哪一個鏈表進行遍歷

void traverse_list(PNODE pHead) {PNODE p = pHead -> pNext;while(NUll != p) //如果 p 不為空(下一個節(jié)點存在){printf("%d\n", p-> data);// p++ ,移動到下一個節(jié)點p = p->pNext;}printf("\n"); }

(3)is_empty

參數(shù): PNODE pHead 判斷是哪一個鏈表
返回值:bool,判斷是否成功

bool is_empty(PNODE pHead) {if(NULL == pHead->pNext) //頭節(jié)點的指針域為空return true;elsereturn false; }

(4)length_list

參數(shù): PNODE pHead 判斷是哪一個鏈表
返回值:int 返回長度

思路:遍歷的時候計數(shù)即可

int length_list(PNODE pHead) {PNODE p = pHead -> pNext;int cnt = 0;while(NUll != p) //如果 p 不為空(下一個節(jié)點存在){cnt++; // 計數(shù)p = p->pNext;}return cnt; }

(5)insert_list

參數(shù):PNODE pHead 判斷是哪一個鏈表
int pos:插入的位置
int val:插入的值 (輸入型參數(shù))
返回值:是否成功

bool insert_list(PNODE pHead,int pos,int val) { // pos 的值必須合法,一共有 5 個節(jié)點,那么插入第 10 個就錯誤 int i = 0; PNODE p = pHead;//移動節(jié)點位置 // 當前節(jié)點不是尾結(jié)點 NULL!=p :說明如果移動到尾節(jié)點就停止移動// 并且移動到第 pos-1 個節(jié)點之前 // 代數(shù):pos=1時,向第一個節(jié)點之前插入,當前p指向頭節(jié)點,不需要執(zhí)行循環(huán) // pos=2時,向第二個節(jié)點之前插入,所以需要執(zhí)行一次。 while(NULL!=p && i<pos-1) {i++;p = p->pNext; }// 如果pos的值不合法的時候 // 或者移動到尾結(jié)點之后,我們在此處進行返回 if(i>pos-1 || NULL==p)return false; // 分配動態(tài)內(nèi)存 PNODE pNew = (PNODE)malloc(sizeof(NODE)); if(NULL == pNew) { printf("insert 動態(tài)內(nèi)存分配錯誤\n"); exit(-1); } // 保存用戶數(shù)據(jù) pNew -> data = val; // 插入節(jié)點// 保存后面節(jié)點的地址 PNODE q = p->pNext;// 然后將前面的節(jié)點指向新申請的節(jié)點 p->pNext = pNew;// 將插入的節(jié)點指向后面的節(jié)點 pNew->pNext = q;return true; }

(6)delete_list

參數(shù):PNODE pHead 判斷是哪一個鏈表
int pos:刪除的位置
int *val:插入的值 (輸出型參數(shù))

bool delete_list(PNODE pHead,int pos,int val) { int i = 0; PNODE p = pHead; //移動節(jié)點位置 // 當前節(jié)點不是尾結(jié)點 NULL!=p :說明如果移動到尾節(jié)點就停止移動// 并且移動到第 pos-1 個節(jié)點之前 // 代數(shù):pos=1時,向第一個節(jié)點之前插入,當前p指向頭節(jié)點,不需要執(zhí)行循環(huán) // pos=2時,向第二個節(jié)點之前插入,所以需要執(zhí)行一次。 while(NULL!=p->Next && i<pos-1) {i++;p = p->pNext; }// 如果pos的值不合法的時候 // 或者移動到尾結(jié)點之后,我們在此處進行返回 if(i>pos-1 || NULL==p->Next)return false;//刪除節(jié)點//保留當前節(jié)點地址 PNODE q = p->pNext;//輸出刪除節(jié)點的內(nèi)容 *val = q->data;//更換指針域 p->pNext = p->pNext->pNext;//釋放內(nèi)存 free(q); q = NULL;return true; }

(7)sort_list

參數(shù):PNODE pHead 判斷是哪一個鏈表
返回值: 無

數(shù)組和鏈表的探討

不同點:一個是連續(xù)的,另一個是離散的。
相同點:都是線性結(jié)構(gòu),算法嚴格來說是一樣的(邏輯上)
比如:都可以使用冒泡來進行排序。(第一個依次和后面比較)

void sort_list(PNODE pHead) {int i, j = 0;int tmp = 0;int len = length_list(pHead);PNODE p,q; // p相當于i, q相當于jfor(i=0,p=pHead->pNext; i < len-1; ++i, p=p->pNext) {for(j=i+1, q = p->pNext ; j <len ; ++j , q= q->pNext){if(p->data > q->data ) // 把小的換到前面來{tmp = p->data;p->data = q->data;q->data = tmp;} } }

補充泛型的初步定義:

算法:(數(shù)組和鏈表的算法一樣嗎?)

狹義的算法:與數(shù)據(jù)的存儲方式,密切相關(guān)
廣義的算法:與數(shù)據(jù)的存儲方式,不相關(guān)

泛型:
利用某種技術(shù):達到不同的存儲方式,執(zhí)行的操作是一樣的。

舉例:運算符的重載

p++:我們可以將 ++ 運算符進行重載。(為 ++ 重寫一個函數(shù))
所以廣義上來說就實現(xiàn)了泛型

3、線性結(jié)構(gòu)的應用 —— 棧

(1)序言

靜態(tài)內(nèi)存:分配在
局部變量
棧序:先進后出

動態(tài)內(nèi)存:分配在
malloc 函數(shù)
堆序:堆排序

棧的定義:事先 “先進后出” 的數(shù)據(jù)結(jié)構(gòu)。(類似于一個杯子)

棧的分類:

靜態(tài)棧:是用數(shù)組來實現(xiàn)
注意:靜態(tài)棧必須提前確定棧的大小(有限的),并且都是連續(xù)的.

動態(tài)棧:是用鏈表來實現(xiàn).
動態(tài)棧可以無限大小(內(nèi)存夠的情況下),并且是不連續(xù)的.

分析棧和鏈表的區(qū)別:
棧只能在棧頂進入,或者是棧頂刪除。

棧的算法:

出棧:
入棧:

(2)棧的算法實現(xiàn)


pBottom:指向頭節(jié)點(里面并不存放有效數(shù)據(jù)),棧底元素的下一個
pTop :指向尾結(jié)點

刪除元素:pTop 向上移動
插入元素:pTop 向下移動

判斷空棧:pTop == pBottom

#include <stdio.h> #include <malloc.h> #include <stdlib.h>// 定義每個節(jié)點的數(shù)據(jù)類型 typedef struct Node {int data; // 數(shù)據(jù)域struct Node *pNext; // 指針域 }NODE, *PNODE;typedef struct Stack {PNODE pTop;PNODE pBottom; }STACK, *STACK;int main(void) {STACK S; // 等價于 struct Stack S // 初始化棧指針initStack(&S); // 一定要思考傳入什么參數(shù) // 壓棧push(&S,1);push(&S,2); // 遍歷輸出traverse(&S); }

(1)init

// 數(shù)入之前:棧指針都是垃圾值 // 1、如果我們的 棧頂指針和棧底指針 都指向一個頭節(jié)點(無用),才能說明我們構(gòu)造了一個空棧 // void init(PSTACK PS) {PS -> pTop = (PNODE)malloc(sizeof(NODE));if(NULL == PS -> pTop){printf("init 動態(tài)分配出錯\n");exit(-1);}else{PS -> pBottom = PS -> pTop;// 將頭節(jié)點的指針域清空PS -> pTop ->pNext = NULL;} }

(2)push

// 1、新申請一個節(jié)點 // 2、入棧的指針域,指向 上一個節(jié)點 // 3、棧頂指針,指向新malloc 的節(jié)點 // 4、 void push(PSTACK PS, int val) {PNODE pNew = (PNODE) malloc(sizeof(NODE));pNew -> pdata = val;// 新申請的節(jié)點的指針域指向上一個節(jié)點,也就是 pTop 指向的節(jié)點pNew -> pNext = PS->pTop; // 棧頂指針,指向新malloc 的節(jié)點PS->pTop = pNew; }

(3)traverse

// 1、先輸出 88 // 思考: // 1、我們不能改變棧頂指針,和棧底指針 // 2、所以我們定義一個臨時的指針p ,指向棧頂元素 // 3、p 指針一個一個向下移動 // 4、p == pBottom 的時候,遍歷完成 void traverse(PSTACK PS) {PSTACK p = PS->pTop;while(p != PS->pBottom){printf("%d ",p->data);p = p->pNext;} return ; }

(4)pop

// 1、保存棧頂節(jié)點的地址,然后釋放 // 2、pTop 向下移動 // 3、將下一個節(jié)點的指針域,指向NULLbool pop(PSTACK PS,int *val) { //棧為空if(PS -> pTop == PS -> pBottom){return false;} // 1、保存棧頂節(jié)點的地址,然后釋放PNODE p = PS ->pTop;*val = p -> data;free(p); // 2、pTop 向下移動PS ->pTop = PS ->pTop -> pNext; // 將下一個節(jié)點的指針域,指向NULLPS ->pTop -> pNext = NULL; }

(5)clear

// 將棧中元素清零,然后節(jié)點還在 // 遍歷一次,然后清除元素 void clear(PSTACK PS) {if (empty(PS)) // 如果為空棧 {return ; }PSTACK p = PS->pTop;while(p != PS->pBottom){p->data = 0;p = p->pNext;} return ; }// 將棧當中的節(jié)點釋放 // 遍歷一次元素,將其釋放 // 但是棧頂指針,和棧底指針都必須留下,留下框架 void clear(PSTACK PS) {if (empty(PS)) // 如果為空棧{return ;}else{PNODE p = PS->pTop;PNODE q = NULL;while(p != PS->pBottom) {q = p->pNext;free(p);p=q;}}return ; }

(3)棧的應用

1、函數(shù)的調(diào)用

int f () {int a,b = 0;g(&a;&b);printf("hello world\n"); }

分析:在 f() 函數(shù)當中調(diào)用g() 函數(shù)的時候,參與棧的使用。

將指令 printf("hello world\n"); 的地址壓入棧
將參數(shù)所用的局部變量 int a,b = 0; 也壓棧

2、中斷

3、表達式求值

4、內(nèi)存分配
5、緩沖處理
6、迷宮

4、線性結(jié)構(gòu)的應用—— 隊列

(1)序言

棧:我們講的是動態(tài)隊列,(本質(zhì)還是鏈表)

什么是隊列?
一種可以實現(xiàn) “先進先出” 的存儲結(jié)構(gòu)。

鏈表的分類?

鏈式隊列:本質(zhì)是鏈表
靜態(tài)隊列:本質(zhì)是數(shù)組

(2)靜態(tài)隊列的分析:

1、靜態(tài)隊列為什么必須是循環(huán)隊列?
2、循環(huán)隊列,需要幾個參數(shù)來確定?
3、循環(huán)隊列,各個參數(shù)的含義?
4、循環(huán)隊列,入隊偽算法講解
5、循環(huán)隊列,出隊偽算法講解
6、如何判斷循環(huán)隊列為空?
7、如何判斷循環(huán)隊列為滿?

1、靜態(tài)隊列為什么必須是循環(huán)隊列?

分析:

rear:用來添加元素的指針(向上移動)
front:用來刪除元素的指針(向上移動)

發(fā)現(xiàn)一個問題:指針都是向上移動,內(nèi)存總有一天會崩潰。(而且使用數(shù)組的時候,數(shù)組的大小是固定的)

解決辦法:循環(huán)隊列

2、循環(huán)隊列,需要幾個參數(shù)來確定?

  • 需要兩個參數(shù):front 指針和 rear 指針。

3、循環(huán)隊列,各個參數(shù)的含義?

  • 2個參數(shù)不同的場合有著不同的含義

(1)隊列初始化:front 和 rear 的值都是

(2)隊列空時:front 和 rear 的值相等,但不一定是

(3)隊列為空:front代表第一個元素,rear代表最后一個元素的下一個元素。

4、循環(huán)隊列,入隊偽算法講解

入隊:在隊尾加入
出隊:在隊頭彈出

5、循環(huán)隊列,出隊偽算法講解


6、如何判斷循環(huán)隊列為空?

如果,front 和 rear 的值相等,則該隊列就一定為空。

7、如何判斷循環(huán)隊列已滿?

1、可以發(fā)現(xiàn),f 和 r 的值可以是任意值

2、可以看出當我們隊列已經(jīng)滿了的時候,指針 p 和 指針 r 是相等的,所以和我們的,隊列已空發(fā)生了沖突。

解決辦法:

1、少使用一個元素
則:當 指針p 和 指針r 互相臨近,則隊列已經(jīng)滿了。
因為:f 和 r 的值可以是任意值,所以當 r = 4 的時候,f 可以變?yōu)?f = 3,f = 5。(其中有一種情況是隊列只有一個元素)
但是,入隊的時候是,r + 1,所以說當 (r+1) % 數(shù)組的長度 == f 的時候,隊列就是滿的,另外一種情況排除。

2、添加一個元素
原理和少用一個元素是相同的

(3)循環(huán)隊列程序演示

#include <stdio.h>typedef struct queue {int *pBase; // 數(shù)組的基地址int front; // 作為數(shù)組元素的下標int rear; }QUEUE,*QUEUE;int main(void) {QUEUE Q;init(&Q);return 0; }

(1)init

//目的: //1、創(chuàng)建一個數(shù)組 //2、下標進行初始化void init(QUEUE *pQ) { // 6 個元素大小pQ -> pBase = (int*)malloc(sizeof(int)*6 );pQ -> front = 0;pQ -> rear = 0; }

(2)en_queue

注意:判斷是否已滿就為少用一個元素,創(chuàng)造了條件

// 入隊:如果隊列不滿 // 1、將值放在 r 當前的位置 // 2、將 r 移動到下一個位置bool en_queue(QUEUE *pQ , int val) {if( full_queue(pQ) ){return false;}else {// 1、將值放在 r 當前的位置pQ->pBase[pQ->rear] = val;// 2、將 r 移動到下一個位置pQ->rear = (pQ->rear+1) % 6;} }

(3)full_queue

bool full_queue(QUEUE *pQ) {// 回顧偽算法if( (pQ->rear + 1)%6 == pQ->front )return true;elsereturn false; }

(4)traverse_queue

void traverse_queue(QUEUE *pQ) {int i = pQ -> front;// i != pQ->rear 時候,有東西要輸出while(i != pQ->rear){printf("%d ",pQ->pBase[i]);i = (i+1) % 6; // 開始循環(huán)} }

(5)out_queue

// 出隊:刪除一個元素 // 1、先將值進行輸出 // 2、指針 f 向上移動 bool out_queue(QUEUE *pQ , int *val) {if( empty_queue() )return false;else{// 1、先將值進行輸出*pVal = pQ->pBase[pQ->front];// 2、指針 f 向上移動pQ->front = (pQ->front + 1) %6;} }

(6)empty_queue

bool empty_queue( QUEUE *pQ ) {if(pQ->rear == pQ->front )return true;elsereturn false; }

(4)隊列的具體的應用

1、所以和時間有關(guān)的操作,都與隊列相關(guān)。

比如:任務,先進先執(zhí)行

遞歸專題

1、前景知識

遞歸定義:不同函數(shù)之間的,相互調(diào)用

#include <stdio.h>void f(); void g(); void k();void f() {printf("FFFF\n");g();printf("1111\n"); } void g() {printf("GGGG\n");k();printf("2222\n"); } void k() {printf("KKKK\n"); }int main(void) {f();return 0; }

自己調(diào)用自己

1、死遞歸:不知道什么停止調(diào)用自己
2、遞歸:一定要知道,自己什么時候停止調(diào)用自己。

#include <stdio.h> // 死遞歸 void f() {printf("1111\n"); }int main(void) {f();return 0; }// 不是死遞歸 void f(int n) {if(n==1)printf("1111\n");elsef(n-1); }int main(void) {f();return 0; }

2、應用舉例

(1)求階乘

n! = n x (n-1)!

(1)使用循環(huán)來實現(xiàn)

#include <stdio.h>int main(void) {int val;int i=0;int mul = 1;printf("請輸入一個數(shù)字:val = ");scanf("%d ",&val);for(i=1, i<=val; i++){mul = i * mul;}printf("%d 的階乘是 %d\n", val, mul);return 0; }

(2)使用遞歸來實現(xiàn)

#include <stdio.h>// 1、出入一個數(shù) // 2、返回這個數(shù)的階乘 long f(long val) {// f(1) 肯定可以實現(xiàn)if(1==n) return 1;// f(n) 要借助 f(n-1) 來實現(xiàn)elsereturn f(n-1) * n; }int main(void) {printf("%d \n",f(5));return 0; }

遞歸的思想
規(guī)模很大的問題的解決,是借助于規(guī)模很小問題解決,當最后規(guī)模最小的問題,不需要再借助其他解決辦法的時候,再倒推回來。

求:100! -> 99! ->98! …-> … …-> 1!
所以,先求 1!,然后再反推。

1、n 規(guī)模問題的解決,可以借助 (n-1) 規(guī)模問題的解決而解決。
舉例:求 100!,我們知道 99!,就可以輕易的得到 100!

(2)求 1+2+3+4+…+100

//long f(long n) { // 規(guī)模最小的時候 n==1if(1==n)return 1; // 剩下的規(guī)模,需要借助 n-1 的規(guī)模來解決 elsereturn f(n-1) + n; }int main(void) {printf("%d \n",f(5));return 0; }

3、對遞歸的理解

定義:一個函數(shù),直接或者間接,調(diào)用自己。

(1)函數(shù)調(diào)用:

當在一個函數(shù)的運行期間調(diào)用另一個函數(shù)時,在運行被調(diào)函數(shù)之前,系統(tǒng)需要完成三件事

1、將所有的實際參數(shù)返回地址等信息傳遞給被調(diào)函數(shù)保存。
返回地址:下一條語句的地址

2、為被調(diào)函數(shù)的局部變量也包括行參)分配存儲空間。

3、將控制轉(zhuǎn)移到被調(diào)函數(shù)的入口。

從被調(diào)函數(shù)返回函數(shù)之前,系統(tǒng)也要完成三件事:

保存被調(diào)函數(shù)的返回結(jié)果。
保存 return 的值

釋放被調(diào)函數(shù)所占的存儲空間。

依照被調(diào)函數(shù)保存的返回地址將控制轉(zhuǎn)移到調(diào)用函數(shù)。

舉例1:

#include <stdio.h>int f(int n) {int i,j;n = n+2;return n; } // f 返回函數(shù),需要做的事情 1、保存 n 的值 2、釋放所有形參、局部變量, 3、根據(jù)保存地址,返回主調(diào)函數(shù)int main(void) {int val;val = f(5);printf("val = %d\n",val);return 0; }// 在 main 函數(shù)當中調(diào)用 f() 函數(shù) 1、將實參 5 ,下一個語句地址 printf 的地址, 2、為形參 n 分配空間 3、控制權(quán)限轉(zhuǎn)移

A函數(shù)調(diào)用A函數(shù),和A函數(shù)調(diào)用B函數(shù),在計算機看來是沒有任何區(qū)別的,只不過用我們?nèi)粘5乃季S方式理解比較怪異而已!

(2)函數(shù)調(diào)用,棧的使用

當有多個函數(shù)相互調(diào)用時,按照”后調(diào)用先返回“的原則,上述函數(shù)之間信息傳遞和控制轉(zhuǎn)移必須借助”“來實現(xiàn)。

即系統(tǒng)將整個程序運行時所需的數(shù)據(jù)空間安排在一個棧中,每當調(diào)用一個函數(shù)時,就在棧頂分配一個存儲區(qū),進行壓棧操作,每當一個函數(shù)退出時,就釋放它的存儲區(qū),就做出棧操作,當前運行的函數(shù)永遠都在棧頂位置。

(3)遞歸調(diào)用,必須滿足的3個條件

  • 遞歸必須得有一個明確的中止條件

  • 該函數(shù)所處理的數(shù)據(jù)規(guī)模必須在遞減(遞歸的值,可以遞增)

// 值在減小、規(guī)模也在減小 int f(int n) {if(n<3)printf("結(jié)束\n")// 遞歸結(jié)束elsen = f(n-1); // 在此遞歸 return n; }// 值在增大、規(guī)模卻在減小 int f(int n) {if(n>7)printf("結(jié)束\n")// 遞歸結(jié)束elsen = f(n+1); // 在此遞歸 return n; }
  • 這個轉(zhuǎn)化必須是可解的

(4)循環(huán)的遞歸的關(guān)系

(1)理論上講,所有的循環(huán)都可以轉(zhuǎn)化為遞歸。但是用遞歸能解決的問題,不一定用循環(huán)可以解決。

(2)遞歸和循環(huán)的特點

遞歸:易于理解、速度比較慢、占用存儲空間大
優(yōu)點:易于理解
缺點:調(diào)用函數(shù),有很大的開銷。

循環(huán):不易理解、速度比較快、占用存儲空間比較小

(5)漢諾塔

如下圖所示,從左到右有A、B、C三根柱子,其中A柱子上面有從小疊到大的n個圓盤,現(xiàn)要求將A柱子上的圓盤移到C柱子上去,期間只有一個原則:一次只能移到一個盤子且大盤子不能在小盤子上面。
求移動的步驟和移動的次數(shù)

解:

(1)n == 1
第1次 1號盤 A---->C sum = 1 次

(2) n == 2
第1次 1號盤 A---->B
第2次 2號盤 A---->C
第3次 1號盤 B---->C sum = 3 次

(3)n == 3
第1次 1號盤 A---->C
第2次 2號盤 A---->B
第3次 1號盤 C---->B
第4次 3號盤 A---->C
第5次 1號盤 B---->A
第6次 2號盤 B---->C
第7次 1號盤 A---->C sum = 7 次

n=1; 1次
n=2; 3次
n=3; 7次
總結(jié):一共是 2 的 n次方,減一。

// 當用戶輸入盤子個數(shù)的時候,我們就假設 A 上有n個盤子,并且從小到大排列好了void hannuota(int n, char A, char B, char C) {如果是一個盤子,直接將 A 柱子上的盤子移動到 C柱子上面否則先將 A 柱子上的 n-1 個盤子借助 C 移動到B上面直接將 A 柱子上的第 n 個盤子移動到上C上面最后將 B 柱子上面的n-1個盤子借助 A 移動到 C 上 }// n:代表要移動盤子的總數(shù) // A:代表準備要移動的柱子,(不一定是 A ,有可能是 B) // B:代表移動過程中借助的柱子(不一定是 B,有可能是 A) // C:代表要接收的盤子的柱子,(也不一定是C)void hannuota(int n, char A, char B, char C) {if(1==n){printf("將編號為 n 的柱子,直接從 %c 柱子,移動到 %c的柱子上面\n",n,A,C);}else{//將 A 上面的 n-1 個盤子,借助 C 移動到 B 上面.hannuota(n-1,A,C,B);//將編號為 n 的盤子,移動到 C 上面printf("將編號為 n 的柱子,直接從 %c 柱子,移動到 %c的柱子上面\n",n,A,C);//hannuota(n-1,B,A,C); } }

總結(jié):其實從宏觀上來說,只需要 3 步(只是其中兩步比較復雜)

1、A上的 n-1 個移動到 B 上 (比較復雜)
這個原理和(將 n 個圓盤從 A 移動到 C 是一樣的)

2、A上的第 n 個移動到 C 上

3、B 上的 n-1 個移動到 C 上(比較復雜)
這個原理和(將 n 個圓盤從 A 移動到 C 是一樣的)

就像將大象放到冰箱里,也需要3步,第二步,將大象放到冰箱比較復雜,但是打開冰箱,和關(guān)閉冰箱比較容易。

4、遞歸的應用

1、樹和森林,就是以遞歸的方式來定義的。
2、樹和圖,很多算法就是以遞歸來實現(xiàn)的。
3、很多數(shù)學公式,就是以遞歸的方式來定義的。

斐波那契數(shù)列:1、2、3、5、8、13、21、34
每個數(shù)都是前兩項相加。

總結(jié)

以上是生活随笔為你收集整理的郝斌——数据结构笔记(数组、链表、栈、队列)(递归)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

中文字幕国语官网在线视频 | 国产成人精品一区二区三区在线 | 日韩影视在线观看 | 国产日韩在线看 | 九九久久国产精品 | 婷婷丁香六月天 | 国产精品18久久久久vr手机版特色 | 日本在线观看一区 | 在线精品亚洲一区二区 | 久久久久综合视频 | 九九视频这里只有精品 | 久久av在线播放 | 亚州av免费 | 开心激情五月婷婷 | av线上看 | 国产成人资源 | 欧美在线观看小视频 | 日本中出在线观看 | 六月婷婷久香在线视频 | 国产一及片 | 免费成人短视频 | 91在线精品视频 | 久久久国产日韩 | 肉色欧美久久久久久久免费看 | 天天操天天操天天操天天操天天操天天操 | 日b视频在线观看网址 | 激情六月婷婷久久 | 狠狠色伊人亚洲综合网站色 | 国产成人av在线 | 国产一级视屏 | av色一区| 中文字幕一区二区三区精华液 | 国产成人在线观看 | 中文字幕国语官网在线视频 | 天天爱天天爽 | av网站在线观看播放 | 国产电影黄色av | 在线国产一区二区三区 | 婷婷五月情 | 国产精品免费一区二区三区 | 亚洲涩涩网站 | 亚洲免费观看在线视频 | 国产色区| 精品国产1区二区 | 国产精品 日韩 欧美 | 在线观看av网站 | 在线导航福利 | 亚洲欧美国产日韩在线观看 | av中文字幕在线免费观看 | 中文字幕av在线电影 | 五月婷婷一区二区三区 | 日韩在线观看三区 | 国产999精品久久久久久麻豆 | 在线观看黄网站 | 久久久久亚洲精品成人网小说 | 久久综合视频网 | 激情婷婷 | 亚洲va欧美va人人爽 | 中文超碰字幕 | 久久在线精品 | 黄色在线看网站 | 国产美女免费看 | 亚洲精品在线观看视频 | 亚洲国产免费网站 | av天天澡天天爽天天av | 亚洲精品国产成人av在线 | 国产性xxxx | 日韩精品视频在线观看网址 | 99久久99久久精品国产片 | 中文字幕精品www乱入免费视频 | 国产一级免费观看 | 亚洲aⅴ在线 | 国产精品永久久久久久久久久 | 国产大陆亚洲精品国产 | 丁香婷婷综合五月 | 四虎在线免费 | 天天干夜夜夜操天 | www.婷婷com | 99久久久久免费精品国产 | 免费国产在线视频 | 色偷偷88欧美精品久久久 | 久久国产网站 | 国产一区二区中文字幕 | 日本中文字幕在线 | 亚洲一区免费在线 | 亚洲综合在线视频 | 综合久久久久久 | 波多野结衣电影久久 | 国产成人精品一区二区在线 | www91在线观看 | 欧美成人性网 | 久久精品99久久久久久2456 | 99国内精品 | 亚洲成人免费 | 免费在线观看黄色网 | 久久精品79国产精品 | av中文字幕在线免费观看 | 亚洲欧洲精品一区二区精品久久久 | 国产精品一区二区av | 麻豆传媒视频观看 | 欧美亚洲国产一卡 | 狠狠躁日日躁狂躁夜夜躁 | 久久国产成人午夜av影院宅 | 97国产大学生情侣酒店的特点 | 国产精品手机在线播放 | 久久国产精品免费一区 | 九九九九九九精品任你躁 | 国产品久精国精产拍 | 欧美精品中文字幕亚洲专区 | 视频国产一区二区三区 | 国产一区观看 | 色久五月| 欧美日韩首页 | 国产在线超碰 | 久久精品a | 97超碰资源总站 | 91视频高清 | 国产精品久久久久久久久久ktv | 黄色三级免费看 | 久久综合狠狠综合久久激情 | 超碰在线公开免费 | 亚洲一区视频在线播放 | 午夜av激情 | 中文字幕 国产 一区 | 亚洲欧美日韩精品久久奇米一区 | 毛片基地黄久久久久久天堂 | 久保带人| 99激情网| 天天做天天爱天天综合网 | av在线永久免费观看 | 国产一区二区播放 | 69av久久| 国产成人性色生活片 | 成人午夜电影在线观看 | 久久99在线视频 | 激情文学丁香 | 在线免费av电影 | 97超碰免费 | 国产精品一区欧美 | 97麻豆视频 | 中文字幕亚洲不卡 | wwxxxx日本| 精品国产一区二区三区久久影院 | 精品国产人成亚洲区 | 国产精品久久久久四虎 | www.91av在线| 国产精品一区二区无线 | 色综合久久久久 | av在线播放一区二区三区 | aaa亚洲精品一二三区 | 亚洲黄色成人av | 九九九视频精品 | 91精品久久久久久久99蜜桃 | 欧美,日韩 | 永久av免费在线观看 | 九九热精品国产 | 韩国一区在线 | 久久亚洲福利 | 国产精品日韩 | 婷婷5月激情5月 | 日韩电影在线观看一区 | 激情综合亚洲 | 超级碰碰免费视频 | 69精品在线观看 | 久草观看 | av黄色免费网站 | 97国产超碰| 亚洲日本色 | 伊人天堂av | 亚洲一区精品人人爽人人躁 | 婷婷福利影院 | 伊人精品影院 | www.狠狠色.com| 欧美成人精品欧美一级乱黄 | 国产成人一区二区三区影院在线 | 黄色av免费 | 超碰在线1 | 国产免费观看高清完整版 | 久久综合五月婷婷 | 天天操天天射天天添 | 日韩专区在线播放 | 久久只精品99品免费久23小说 | 久久成视频 | 国产在线综合视频 | 国产精品女教师 | 日韩电影在线看 | 国产一区二区高清不卡 | 91亚洲视频在线观看 | 国产日韩亚洲 | 日日干 天天干 | 国产成人精品999 | 全久久久久久久久久久电影 | 国产精品福利一区 | 久久精品艹 | 亚洲精品天天 | 亚洲一区日韩精品 | 国产一区高清在线观看 | 国产精品亚洲片夜色在线 | 亚洲精品视频在 | 久热色超碰| 综合色中文| 六月丁香综合网 | 夜夜视频资源 | 天天狠狠操 | 欧美成年网站 | 久久精品一区二区三区四区 | 视频一区视频二区在线观看 | 久久精品99视频 | 日韩videos | 欧美一级裸体视频 | 亚洲欧美成人网 | 日批视频国产 | 婷婷在线观看视频 | 成人黄色在线看 | 夜夜操天天干 | 丁香婷婷综合色啪 | 欧美成人xxxx | www.五月婷| 精品1区2区3区 | 日韩色爱| 91免费视频国产 | 久久久久久免费视频 | 在线观看av片| 久久久久成人精品免费播放动漫 | 天天操操 | 国产a国产a国产a | 国产一级不卡毛片 | 黄色成人av在线 | 91在线免费观看国产 | 999视频在线播放 | 99精品乱码国产在线观看 | 韩国av免费在线观看 | 国产美女精品视频 | 国产精品久久一卡二卡 | 国产原厂视频在线观看 | 五月婷网 | 国产精品久久久久久久毛片 | 99久e精品热线免费 99国产精品久久久久久久久久 | 一区二区三区在线免费观看视频 | 中文区中文字幕免费看 | 五月天国产精品 | 久久精品直播 | 日日夜夜亚洲 | 丁香五香天综合情 | 九九热只有这里有精品 | 在线高清| 超碰伊人网 | 日日操夜夜操狠狠操 | 国内视频在线观看 | 国产分类视频 | 91女子私密保健养生少妇 | 中文免费 | 久久五月婷婷丁香社区 | 国产免费久久精品 | 天天射天天操天天色 | www.五月天婷婷| 免费观看久久 | 日日干天天爽 | 99久久爱 | 激情五月开心 | 深爱激情五月综合 | 最新国产在线视频 | 久久久午夜精品理论片中文字幕 | 国产亚洲在线观看 | 国产视频二| 国产视频中文字幕在线观看 | 99精品亚洲| 久久伊人八月婷婷综合激情 | 亚洲在线黄色 | 久久任你操 | 人人插人人玩 | 国产xvideos免费视频播放 | 97精品国自产拍在线观看 | 中文字幕av全部资源www中文字幕在线观看 | 欧美五月婷婷 | 国产一级在线 | 亚洲午夜精品久久久 | 狠狠插狠狠干 | 天天爱天天 | 五月婷婷在线视频观看 | 久久免费公开视频 | 欧洲av不卡 | www.超碰97.com | 中文字幕乱码电影 | 免费a级毛片在线看 | 亚洲精品乱码久久久久久高潮 | 99精品亚洲 | 精品日韩av| 国产色区| 黄色免费大全 | 欧美日韩在线视频一区二区 | 亚洲 中文 在线 精品 | 最近最新mv字幕免费观看 | 国产精品成人自产拍在线观看 | 在线观看深夜视频 | 五月天激情视频 | 中文字幕高清有码 | a'aaa级片在线观看 | 欧美国产日韩一区二区 | 黄色aa久久 | 中文字幕精品视频 | 探花视频在线观看免费 | 日本黄色免费在线观看 | 亚洲精选视频免费看 | 国产精选在线观看 | 在线精品在线 | 精品国产伦一区二区三区观看体验 | 精品一区二区三区久久久 | 国产成人在线综合 | 日韩免费不卡av | 99久久99久久精品国产片果冰 | 精品久久网 | 欧美日韩3p | 精品91| 爱色av.com | 狠狠网站| av网站播放 | 麻豆视频免费入口 | 久久久亚洲网站 | 欧美日韩成人一区 | 超碰97人人干 | 亚洲精品tv | 国产一级在线看 | 草免费视频 | 久久视频一区二区 | 中文字幕中文字幕在线中文字幕三区 | 国产精品igao视频网网址 | 欧美在线视频一区二区三区 | av三级av | 久久99热这里只有精品 | 久久久久久久久影院 | 97夜夜澡人人双人人人喊 | adn—256中文在线观看 | 国产精品入口麻豆www | 一级黄色毛片 | 精品国产视频一区 | 日韩免费观看视频 | www黄色大片 | 国产色就色 | 天天弄天天干 | 制服丝袜欧美 | 免费人做人爱www的视 | 久久免费国产 | 久久综合精品一区 | 国产精品一区二区三区视频免费 | 高清av影院| 欧美色噜噜 | 黄色高清视频在线观看 | 九九九九热精品免费视频点播观看 | 成人手机在线视频 | 99精品热视频 | 99久久精品免费视频 | 一级欧美一级日韩 | 天天看天天操 | 99久久婷婷国产综合精品 | 在线观看欧美成人 | 五月婷婷导航 | 欧美日韩中文在线观看 | 美国av大片 | 99热国产精品 | 欧美性色黄| av成人在线看 | 狠狠躁夜夜躁人人爽视频 | 日韩精品视频免费专区在线播放 | 国产成人精品在线播放 | 9色在线视频 | 成人久久18免费网站图片 | 手机av看片 | 国产精品福利在线观看 | 欧美日韩精品在线视频 | 99色免费 | 亚洲精品资源在线观看 | 69国产精品视频免费观看 | av激情五月 | 欧美精品二区 | 欧美日产在线观看 | 日日噜噜噜噜夜夜爽亚洲精品 | 国产免费二区 | 亚洲女欲精品久久久久久久18 | av在线一二三区 | 国产精品久久久久久吹潮天美传媒 | 九九久久久久久久久激情 | 奇米四色影狠狠爱7777 | 丁香花在线观看免费完整版视频 | 久久午夜影院 | 激情综合网五月 | 国产精品一区二区三区免费视频 | 久久亚洲成人网 | 九九九九精品九九九九 | 麻豆影视网 | 九九在线国产视频 | 亚洲国产精品影院 | 中文字幕在线播放视频 | 日日夜夜天天人人 | 日批视频在线观看免费 | 人人dvd| av成人资源 | 欧美精品中文在线免费观看 | 99一区二区三区 | 九九免费在线观看视频 | 亚洲成a人片综合在线 | 国产乱码精品一区二区蜜臀 | 在线视频免费观看 | 精品国自产在线观看 | 亚洲国产网站 | 在线观看mv的中文字幕网站 | 亚洲国产免费网站 | 成人国产精品久久久 | 国产精品aⅴ | av网站有哪些 | 国产在线视频一区 | 日韩中文字幕电影 | 人人干干人人 | 夜夜操天天干 | 涩涩成人在线 | 香蕉视频在线免费 | 一区二区视频播放 | 国产超碰在线 | 外国av网 | 国产免费人成xvideos视频 | 在线播放亚洲激情 | 国产无吗一区二区三区在线欢 | 午夜视频免费 | 手机成人在线 | 久草在线视频国产 | 热久久免费视频 | 久久久久亚洲国产精品 | 在线观看黄色 | 中文字幕在线观看免费高清电影 | 亚洲国产精品成人va在线观看 | 国产一区二区播放 | 成人在线黄色电影 | 黄污视频网站大全 | 久久韩国免费视频 | 最新中文字幕在线播放 | 精品视频一区在线观看 | 一区二区三区国产欧美 | 97国产大学生情侣酒店的特点 | av看片网| 国产精品黑丝在线观看 | 久久久福利视频 | 国产精品无av码在线观看 | 亚洲 欧洲av| 99视频这里有精品 | 国产在线探花 | av在线进入| 欧美巨大荫蒂茸毛毛人妖 | 韩国av在线| 96久久| 337p西西人体大胆瓣开下部 | 欧美日韩在线精品 | 欧美日韩精品在线播放 | 亚洲经典视频 | a√天堂资源 | 成人午夜免费剧场 | 97碰在线视频 | 五月天com | 日韩素人在线观看 | 91福利社在线观看 | 日日干av | 婷婷丁香狠狠爱 | 九九交易行官网 | 午夜精品99久久免费 | 久久综合久久综合这里只有精品 | 黄色午夜| 丁香六月婷婷综合 | 丁香五月亚洲综合在线 | 国产欧美最新羞羞视频在线观看 | 91精品综合在线观看 | 亚洲在线网址 | 亚洲综合欧美日韩狠狠色 | 日韩三级久久 | 99精品在线观看视频 | 久久不卡电影 | 国产91九色视频 | av在线com | 国产高清av免费在线观看 | 色婷婷国产精品 | 97视频人人 | 蜜臀aⅴ国产精品久久久国产 | 国产精品18久久久久白浆 | 久草久热 | 亚洲aⅴ免费在线观看 | 中文字幕资源在线 | 国产最新视频在线观看 | 精品国产免费观看 | 国产精品久久艹 | 国产91精品看黄网站在线观看动漫 | 最新中文在线视频 | 国产又粗又长又硬免费视频 | 久久久久久久久久久网站 | 亚洲成av人片在线观看www | 友田真希x88av| 一区二区三区精品在线视频 | www久久精品 | 欧美日韩在线观看一区二区 | 最新一区二区三区 | 国产小视频在线免费观看 | 亚洲精品免费在线观看视频 | 不卡av在线免费观看 | 亚洲精品乱码久久久久v最新版 | 91视频91蝌蚪 | 国产二级视频 | 一区二区三区观看 | 69国产精品视频 | 免费成人在线电影 | 国产永久免费 | 91在线视频精品 | 欧美一级视频免费看 | 韩国一区二区av | www色网站| 欧美天天综合 | 国产v欧美 | 狠狠狠色丁香婷婷综合久久88 | 免费看黄色大全 | 在线亚洲天堂网 | 久久毛片网站 | 日日草视频| 欧美精品一二 | 国产短视频在线播放 | 天天爱天天射天天干天天 | 成人av中文字幕在线观看 | 一区二区三区在线免费 | 日韩中文三级 | 欧美黑人猛交 | 国产精品都在这里 | 一区精品在线 | 国产91精品一区二区 | 精品国产一区二区三区在线观看 | 国产中文在线字幕 | 日韩精品不卡在线观看 | 精品你懂的 | 日日激情| 精品亚洲成a人在线观看 | 天天操天天操天天操天天操 | 在线观看中文字幕视频 | 亚洲男男gaygay无套 | 国产99久久99热这里精品5 | 2019中文字幕第一页 | 欧美国产日韩在线观看 | 在线观看91久久久久久 | 91激情 | 日韩网 | 久久看看| www夜夜操 | 色噜噜日韩精品一区二区三区视频 | 91精品视频网站 | 欧美一区在线看 | 国产精品一区在线观看 | 九草视频在线 | 91精品国产网站 | 日日夜夜天天操 | 国产成人av一区二区三区在线观看 | 国产精品激情 | 国产成人精品亚洲a | 亚洲mv大片欧洲mv大片免费 | 亚洲精品av中文字幕在线在线 | 99精品视频在线观看播放 | 欧美日韩另类在线观看 | 日本公乱妇视频 | 中文字幕一区二区三区在线播放 | 操操综合 | 碰天天操天天 | 免费成人在线视频网站 | 亚洲国产精品一区二区久久hs | 国产91亚洲精品 | 精品中文字幕在线观看 | 欧美精品一二三 | 国产 成人 久久 | 蜜臀av性久久久久蜜臀aⅴ流畅 | 天堂av免费在线 | 日韩欧美视频一区二区 | 免费瑟瑟网站 | 成人午夜精品久久久久久久3d | 五月天av在线 | 国产精品永久免费观看 | 在线观看国产日韩 | 久久久96 | 91福利视频在线 | 国产欧美精品在线观看 | 91爱爱免费观看 | 亚洲欧洲精品视频 | 成人国产精品久久久久久亚洲 | 麻豆精品视频 | 手机av在线免费观看 | 亚洲精品视频网址 | 在线免费观看国产黄色 | 黄色大片av | 91精品在线看 | 婷婷国产在线观看 | 日日夜夜精品免费 | 欧美日韩在线观看不卡 | 依人成人综合网 | 伊人天天色 | 天天操天天拍 | 亚洲精品乱码久久久久v最新版 | 精品中文字幕在线 | 91禁看片 | 久草免费电影 | 国产精品麻豆视频 | 国产精品免费观看国产网曝瓜 | 91桃色国产在线播放 | 亚洲国产手机在线 | 日韩成人免费在线观看 | 久久久久亚洲精品国产 | 久久精品国产精品亚洲 | 国产一级精品在线观看 | www黄色com | 色婷婷五 | 91看片在线免费观看 | 在线观看第一页 | 一区二区网 | 国产小视频免费在线观看 | 国产在线观看午夜 | 色婷婷丁香 | 美女网站色免费 | 深夜视频久久 | 成人免费看片网址 | 中文成人字幕 | 天天操天天射天天插 | 中文字幕在| 国产视频1区2区3区 久久夜视频 | 久久久精品免费观看 | 久操中文字幕在线观看 | 天天av综合网| 日韩av黄| 欧美 国产 视频 | 91天天操 | 香蕉在线影院 | 久久99热这里只有精品国产 | 日韩成人不卡 | 亚洲五月花 | 国产成人精品一区二区三区网站观看 | 又黄又爽又色无遮挡免费 | 久久久久久伊人 | 人人看人人草 | 婷婷五月在线视频 | 999国内精品永久免费视频 | 在线播放一区 | 欧美一级视频在线观看 | 亚洲精品视频播放 | 国产精品毛片久久 | 久久视频国产精品免费视频在线 | 99久久久国产精品 | 国产a视频免费观看 | 欧美精彩视频 | av久久在线| 91色九色 | www.久久com | 久久看视频 | 日本少妇久久久 | 99产精品成人啪免费网站 | 91九色在线观看视频 | 日韩手机在线观看 | aaa日本高清在线播放免费观看 | 亚洲国产理论片 | 欧美午夜激情网 | 69av久久| 日本电影久久 | 99久久精品国 | 一区二区欧美日韩 | 亚洲国产精品va在线看 | av女优中文字幕在线观看 | 国产在线播放观看 | 免费网站v | 免费观看黄色12片一级视频 | 国产精品美女999 | 超碰97.com| 久久中文字幕视频 | 黄色av一区二区三区 | 玖玖精品在线 | 在线免费观看黄色 | 国产精品高清在线 | 99这里只有 | 日韩深夜在线观看 | 久久 地址 | 久久国产免 | 97色se| 久久伊人色综合 | 伊人小视频 | 国产精品资源在线 | 亚洲国产午夜视频 | 日韩特黄av | 色偷偷88欧美精品久久久 | 碰碰影院| 亚洲伦理电影在线 | 97免费| 国产精品中文在线 | 精品国模一区二区三区 | 国产96在线 | 韩国av一区 | 伊人午夜 | 五月婷婷欧美视频 | 毛片一二区 | 日韩在线视频免费观看 | 国产伦理剧 | 亚洲日本色 | 日本黄色黄网站 | 91精品在线观看入口 | 日韩精品中文字幕一区二区 | 久久综合九色综合网站 | 免费看三级网站 | 久久综合久久综合久久 | 国产精品白丝jk白祙 | 在线观看黄色大片 | 日韩有色 | 就要色综合 | 91麻豆精品国产91久久久更新时间 | 91精品蜜桃| 91高清完整版在线观看 | 九九热1| www.婷婷com | 亚洲黄色免费网站 | 日韩欧美视频一区二区三区 | 97色婷婷| 亚洲精品美女 | 精品国产一区二区三区免费 | 久久久综合九色合综国产精品 | 久久综合视频网 | 不卡av电影在线观看 | 久久精品视频4 | 日韩成片| 91视频91色| 热久在线| 日韩a欧美 | 黄色aaaaa| 国产精品国产毛片 | 国产免费黄视频在线观看 | 人人添人人澡人人澡人人人爽 | av在线一级| 欧美成人精品欧美一级乱 | 美女网站黄免费 | 精品国产aⅴ一区二区三区 在线直播av | 国产精品久久久久久久久久久久午夜 | 日韩美精品视频 | 国产精品高潮呻吟久久av无 | 久久女教师| 91传媒在线观看 | 国产综合精品久久 | 久久精品中文 | 日韩一区二区三免费高清在线观看 | 欧美a性 | 天天射天天添 | 欧美国产日韩一区二区三区 | 日韩精品在线播放 | 五月天激情在线 | 91九色蝌蚪国产 | 日韩在线不卡视频 | 久视频在线播放 | 91资源在线播放 | 免费看片色 | 日韩精品五月天 | 麻豆高清免费国产一区 | 国产精品视频全国免费观看 | 国产盗摄精品一区二区 | 亚洲日日夜夜 | 亚洲亚洲精品在线观看 | 在线观看一二三区 | 狠狠88综合久久久久综合网 | 在线观看成人一级片 | 欧美视频www| 久久综合婷婷国产二区高清 | 在线观看av中文字幕 | 中文字幕精品一区久久久久 | 四虎影视成人永久免费观看亚洲欧美 | 国产在线国偷精品产拍 | 日韩电影在线一区二区 | 91成人短视频在线观看 | 国产精品久久久久一区二区国产 | 九九九热精品免费视频观看网站 | 1024手机基地在线观看 | wwwav视频| 亚洲日韩欧美一区二区在线 | 色综合天天做天天爱 | 久久久黄色av | 91人人澡| 国产在线理论片 | 麻豆精品91| 黄色成人av| 婷婷色网| 欧美性大战久久久久 | 一级欧美黄 | 欧美一级大片在线观看 | 久久99精品久久久久久 | 色婷婷av一区 | 韩国av三级| 成人久久久久久久久久 | 亚洲欧洲在线视频 | 中文字幕电影网 | 韩国中文三级 | 精品国产_亚洲人成在线 | 黄色日本免费 | 日韩在线观看一区二区 | 四虎在线免费观看视频 | 国产精品欧美一区二区三区不卡 | 国产精品一区二区久久久 | 久久一区二区免费视频 | 午夜精品福利一区二区 | 日韩在线视频一区 | 国产午夜精品一区二区三区四区 | 午夜一级免费电影 | 国产精品刺激对白麻豆99 | 国产亚洲精品久久久久久网站 | 青草草在线 | 亚洲成a人片77777潘金莲 | 探花视频在线版播放免费观看 | av观看久久久 | 久草视频99 | 久久久久久久久久国产精品 | 亚洲天天在线 | 精品国产免费人成在线观看 | 精品99免费视频 | 久久视频在线观看免费 | 亚洲丝袜中文 | 欧美成人精品欧美一级乱黄 | 亚洲综合激情五月 | 久久69精品久久久久久久电影好 | 久久人人97超碰国产公开结果 | a级国产片 | 午夜久久久精品 | 久一久久 | 久久久91精品国产一区二区三区 | 色狠狠一区二区 | 韩国在线一区 | 国产免费一区二区三区最新 | 精品福利视频在线 | 久久久久伦理电影 | 97av在线视频免费播放 | 成 人 黄 色视频免费播放 | 久草视频在线看 | 国产精品去看片 | 免费色视频网址 | 中文字幕中文字幕在线中文字幕三区 | 在线韩国电影免费观影完整版 | 欧美巨乳波霸 | 色瓜 | 国产一区麻豆 | 亚洲激情p | 在线观看成人福利 | 国产精品成人国产乱一区 | 亚洲黄色小说网 | 超碰精品在线 | 久久99久久精品国产 | 欧美二区视频 | 日韩欧美一二三 | 国产精品v a免费视频 | 色婷婷亚洲 | 99国产一区二区三精品乱码 | 色播五月激情综合网 | 精品久久福利 | 亚洲理论电影网 | 国产一区二区在线视频观看 | 日韩深夜在线观看 | 成人a视频片观看免费 | 国产精品久久久久久久7电影 | 青春草视频 | 国内99视频 | 国产亚洲高清视频 | 国产福利av在线 | 视频成人永久免费视频 | 91观看视频 | 92中文资源在线 | 国产香蕉视频在线观看 | 成人一区二区三区在线 | 狠狠色噜噜狠狠 | 国产丝袜一区二区三区 | 国产视频在线一区二区 | 国产精品第2页 | 亚洲成av| 在线一区电影 | 97热在线观看 | 亚洲激情中文 | 92国产精品久久久久首页 | 伊人五月 | 中文字幕文字幕一区二区 | 色资源二区在线视频 | 高清不卡免费视频 | av在线播放免费 | 伊人国产在线播放 | 成人污视频在线观看 | 国产精品美女在线观看 | 久久精品国产精品 | 婷婷五天天在线视频 | 日韩欧美精品在线 | 亚洲成av人片在线观看 | 色综合人人| 欧美激情综合五月色丁香小说 | 人人插人人艹 | 国产精品2019 | 黄色性av| 午夜精品久久久99热福利 | 91九色视频观看 | 五月婷婷中文网 | 国产黄色精品在线 | 日韩三级在线观看 | 国产一区二区不卡在线 | 999成人精品| 国产99一区 | 91亚色视频在线观看 | 一级做a爱片性色毛片www | 91视频久久| 欧美极品一区二区三区 | 国产永久网站 | 中文字幕一区二区三区久久蜜桃 | 中文字幕欧美日韩va免费视频 | 国产麻豆剧传媒免费观看 | 91久久国产露脸精品国产闺蜜 | 久久国产一二区 | 丁香婷婷激情五月 | 久久久国产精品人人片99精片欧美一 | 人人澡超碰碰97碰碰碰软件 | 久久综合五月 | 嫩小bbbb摸bbb摸bbb | 天天天综合网 | 99久久精品日本一区二区免费 | 精品视频不卡 | 亚洲 av网站 | www麻豆视频 | 久久蜜臀av | 日韩免费在线观看视频 | 91在线网站 | 成年人三级网站 | 天天爱天天干天天爽 | 99爱这里只有精品 | 人人看人人做人人澡 | 91中文字幕在线 | 欧美精品v国产精品 | 久久婷婷五月综合色丁香 | 久久免费观看少妇a级毛片 久久久久成人免费 | 天天操天天射天天爱 | 天天操,夜夜操 | 色姑娘综合网 | 久草在线免费看视频 | 色综合天天狠天天透天天伊人 | 狠狠躁日日躁夜夜躁av | 免费涩涩网站 | 91亚瑟视频 | 九九久久久久久久久激情 | 午夜在线免费视频 | 日韩一区二区三区在线观看 | 天天综合网天天综合色 | a黄在线观看 | 三级在线视频播放 | 久精品在线 | 欧美性一级观看 | 国产精品麻豆99久久久久久 | 久久久久久久久久久免费视频 | 成人免费视频网 | 久久人人爽av | 2024av| 亚洲成色777777在线观看影院 | 日韩中文字幕免费电影 | 亚洲三区在线 | 99国产在线 | 欧美射射射 | 91亚洲影院 | 免费av视屏 | 午夜精品视频一区 | 久久综合九色综合久久久精品综合 | 精品毛片一区二区免费看 | 中文字幕黄色网址 | 黄色片毛片 | 日韩免费观看高清 | 久久免费的精品国产v∧ | 日韩av电影免费在线观看 | 成av人电影 | 干亚洲少妇 | 五月婷网站 | 日本特黄特色aaa大片免费 | 99久久久久国产精品免费 | 一区二区三区 亚洲 | 免费a视频 | 久久久免费观看视频 | 中文字幕久久久精品 | 国产一区二区不卡视频 | 99精品视频在线观看视频 | 精品不卡av | 国产伦精品一区二区三区高清 | 人人爽人人澡人人添人人人人 | 天天射射天天 | www.com久久久 | 99精品亚洲 | adc在线观看 | www黄色com | 麻花豆传媒mv在线观看网站 | 精品中文字幕在线观看 | 欧美一级片播放 | 中国一级特黄毛片大片久久 | 成人在线视频论坛 | 久久手机精品视频 | 久久久久国产精品免费网站 | 日日噜噜噜噜夜夜爽亚洲精品 | 亚洲午夜精品久久久久久久久 | 日韩免费二区 | 色妞色视频一区二区三区四区 | 国产精品乱码一区二区视频 | 国产中文字幕国产 | 日日干夜夜草 |