数据结构与算法概述讲座总结一——链表

来源:互联网 发布:js application对象 编辑:程序博客网 时间:2024/06/03 20:12

为了让我们能对数据结构和算法有一个初步的认识,使得我们在平时的编程过程中能更有调理和效率,同时也是为了让我们在进入大二开始学习数据结构和算法之前能带我们入门了解,小组开展了为期四期的数据结构与算法专题讲座。

第一期的讲座主要介绍了数据结构和算法的基本概念,在此进行总结,希望能通过总结将讲座知识充分吸收。

对于一个新概念或者新知识,我们需要弄明白它是什么,为什么要学习它,只有弄明白这两点后,才能更好的理解它,并在今后能有目的的去学习它。

那么

什么是数据结构?为什么要学习数据结构?
什么是算法?为什么要学习算法?
数据结构和算法之间有什么关系?

根据概念:

数据结构(Data Structure):是指相互之间具有(存在)一定联系(关系)的数据元素的集合。

算法(Algorithm): 解决问题的步骤的描述,在计算机中表现为指令的有限序列

《算法与数据结构》是计算机科学中的一门综合性专业基础课。是介于数学、计算机硬件、计算机软件、三者之间的一门核心课程,不仅是一般程序设计的基础,而且是设计和实现编译程序、操作系统、数据库系统以及其他操作系统和大型应用程序的重要基础。

可以看出,对于选择了计算机行业的我们,数据结构和算法能然我们在编程过程中理解数据的间的关系从而能更有效的操作数据,能让我们对得到相应结果的步骤的设计更加行云流水,再者,数据结构和算法之间存在的关系更是让加深我们对编程和计算机的理解,因此,学习这门知识十分有必要。

——关于数据结构:

一.数据结构的相关术语

术语 对应英文全称 抽象数据类型 Abstract Data Type 稠密索引 Dense index 数据 Data 稀疏索引 Sparse index 数据元素 Data element 抽象数据类型 Abstract DataType 数据项 Data item 算法 Algorithm 数据结构 Data structure 正确性 Correctness 逻辑结构 Logical structure 可读性 Readability 数据类型 Data type 健壮性 Robustness 指针 Pointer 频度 Frequency count 顺序存储结构 Sequential storage structure 时间复杂度 Time complexity 链状存储结构 Linked storage structure 空间复杂度 Space complexity

对于入门,仅作为了解,我们只需理解其中几个重点术语的含义:

数据(Data) :客观事物的符号表示
数据元素(Data Element) :数据的基本单位
数据对象(Data Object):性质相同的数据元素的集合

二.数据的逻辑结构和物理结构

数据的逻辑结构表现了数据元素间的逻辑关系

这里写图片描述

而数据的物理结构反映了数据在计算机内部的存储安排

如顺序存储、链式存储等数据在计算机内部存储的方式。

两者之间有如下的简单联系

这里写图片描述

——关于算法:

一.算法的特性
1.I/O :算法具有0个或者多个输入,至少有一个输出
2.有穷性:无死循环,能在可以接受的时间内完成
3.确定性:算法的每一步骤都具有确定的含义,不会出现二义性。
4.可行性:算法的每一步都必须是可行的。

很明显的,对于第一点,算法是解决问题的步骤的描述,而
在步骤执行完毕后,如没有至少一个的结果输出,那么走过的解决问题的步骤是没有意义的,因为我们并没有通过步骤得到所需要的结果。对于第二点,我们需要通过一个算法得到我们向要的结果时,首先肯定是要得到结果,因此不能造成死循环,同时,如果一个算法会花费太多的时间,那也是没有意义的(比如100年之类的……)。对于第三点,我们队一个问题的解决就是为了得到一个确切的答案,而作为解决问题步骤描述的算法如果出现了二义性,就无法保障答案的准确性。对于第四点,和第三点类似的,如步骤不可行,我们也不能得到想要的答案。

二、算法的设计要求(评定标准)

1.正确性
2.可读性
3.健壮性
4.时间效率高,储存量低(最少的空间消耗,最少的时间)

正确性和可读性相比无需多说,健壮性也叫做容错性,它指代了一个算法对不合理输入的反映能力和处理能力。

在说明第四点前先简单介绍时间复杂度和空间复杂度的概念:

算法复杂度分为时间复杂度和空间负责度,时间复杂度是指执行算法所需要的计算工作量,而空间复杂度是指执行这个算法所需要的内存空间。

对于时间复杂度,首先有如下概念:

指代符号 含义 n 问题规模 T(n) 语句总执行次数 f(n) 关于规模n的函数

时间复杂度记做:T(n) = O(f(n)) (大O记法)(随n增长,T(n)增长越慢的算法越优秀)

对于算法函数,有如下分类:

分类 指代符 常数阶 O(1) 对数阶 O(logn) 线性阶 O(n) 线性对数阶 O(nlog2n) 平方阶 O(n^2) 立方阶 O(n^3) k次方阶 O(n^k) 指数阶 O(2^n)

他们存在如下关系:
O(1) < O(logn) < O(n) < O(nlog2n) < O(n^2) < O(n^3) < O(n^k) < O(2^n ) < O(n!) < O(n^n)

而对于空间复杂度则和时间复杂度类似,记做S(n)=O(f(n))

那么回到第四点,因为对于计算机而言,最重要的两项资源便是时间资源和空间资源,因此只有做到最少的空间消耗和最少的时间,才能通过算法使我们的程序更加高效。

——关于线性表

一、概念
根据百度百科:线性表是最基本、最简单、也是最常用的一种数据结构。线性表中数据元素之间的关系是一对一的关系,即除了第一个和最后一个数据元素之外,其它数据元素都是首尾相接的(注意,这句话只适用大部分线性表,而不是全部。)
PS:一般而言,一般线性表的作用就是存储数据。

二、线性表的物理结构
分为连续式和非连续式,体现在是使用连续内存还是使用非连续内存上的实现方式上。

三、线性表的简单例子-链式存储-链表
1.概念:用一组任意的存储单元存储线性表中的数据元素。
用这种方法存储的线性表简称线性链表 。

2.关于链表
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。但链表相比于线性表顺序结构,操作复杂。链表由于不必须按顺序存储,链表在插入的时候只有O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(n)和O(1)。

3.对链表基本功能的实现(简单练习)
链表一般可以细分为带头节点的单链表、带头节点的单向循环链表、带头节点的双向链表、带头节点的双向循环链表、带头指针的单链表、带头指针的单向循环链表、带头指针的双向链表、带头指针的双向循环链表,在此,以简单的带头节点的单链表实现链表的基本操作。

基本设定:

#include<stdio.h>#include<stdlib.h>#include<string.h>struct number{    int num;    struct number *next;};int Create(struct number *phead);int Display(struct number *phead);int InsertHead(struct number *phead);int InsertEnd(struct number *phead);int InsertPlace(struct number *phead);int InsertSearch(struct number *phead);int Delete(struct number *phead);int Reverse(struct number *phead);int Search(struct number *phead);int Destory(struct number *phead);int main(){    struct number *phead = (struct number *)malloc(sizeof(struct number));    phead -> next = NULL;    return 0;}

链表的创建:

int Create(struct number *phead){    char ch[5];    struct number *ptemp,*pnew;    ptemp = phead;    while(1){        printf("Do you want to add a node?(Y/N)\n");        scanf("%s",ch);        if(strcmp(ch,"y") == 0||strcmp(ch,"Y") == 0){            pnew = (struct number *)malloc(sizeof(struct number));            ptemp->next = pnew;            pnew->next = NULL;            ptemp = ptemp->next;            printf("Please input a number:\n");            scanf("%d",&ptemp->num);        }        else if(strcmp(ch,"n") == 0||strcmp(ch,"N") == 0){            break;        }        else{            printf("Can not recognition!\n");        }    }    return 0;}

遍历链表:

int Display(struct number *phead){    struct number *ptemp;    ptemp = phead->next;    if(ptemp == NULL){        printf("Can not find any nodes!\n");        return -1;    }    while(ptemp != NULL){        printf("%d ",ptemp->num);        ptemp = ptemp->next;    }    printf("\n");    return 0;}

链表的插入:

头插

int InsertHead(struct number *phead){    char ch[5];    struct number *pnew,*ptemp;    if(phead->next == NULL){        printf("Can not find any nodes!\n");        return -1;    }    while(1){        printf("Do you want to insert a node?(Y/N)\n");        scanf("%s",ch);        if(strcmp(ch,"y") == 0||strcmp(ch,"Y") == 0){            pnew = (struct number *)malloc(sizeof(struct number));            ptemp = phead->next;            phead->next = pnew;            pnew->next = ptemp;            printf("Please input a number:\n");            scanf("%d",&pnew->num);        }        else if(strcmp(ch,"n") == 0||strcmp(ch,"N") == 0){            break;        }        else{            printf("Can not recognition!\n");        }    }    return 0;}

尾插

int InsertEnd(struct number *phead){    char ch[5];    struct number *ptemp,*pnew;    ptemp = phead;    if(ptemp->next == NULL){        printf("Can not find any nodes!\n");        return -1;    }    while(ptemp->next != NULL){        ptemp = ptemp->next;    }    while(1){        printf("Do you want to insert a node?(Y/N)\n");        scanf("%s",ch);        if(strcmp(ch,"y") == 0||strcmp(ch,"Y") == 0){            pnew = (struct number *)malloc(sizeof(struct number));            ptemp->next = pnew;            ptemp = ptemp->next;            printf("Please input a number:\n");            scanf("%d",&pnew->num);        }        else if(strcmp(ch,"n") == 0||strcmp(ch,"N") == 0){            break;        }        else{            printf("Can not recognition!\n");        }    }    return 0;}

指定位置插入

int InsertPlace(struct number *phead){    unsigned short i,where,go = 0;    char ch[5];    struct number *pnew,*ptemp,*pend;    if(phead->next == NULL){        printf("Can not find any nodes!\n");        return -1;    }    while(1){        pend = phead;        printf("Do you want to insert a node?(Y/N)\n");        scanf("%s",ch);        if(strcmp(ch,"y") == 0||strcmp(ch,"Y") == 0){            printf("Please input the sequence you want to insert.\n");            scanf("%lu",&where);            for(i = 1;i < where;i++){                if(pend->next == NULL){                    printf("Can not find the sequence!\n");                    go = 1;                    break;                }                pend = pend->next;            }            if(go == 1){                go = 0;                continue;            }            ptemp = pend->next;            pnew = (struct number *)malloc(sizeof(struct number));            pend->next = pnew;            pnew->next = ptemp;            printf("Please input a number:\n");            scanf("%d",&pnew->num);        }        else if(strcmp(ch,"n") == 0||strcmp(ch,"N") == 0){            break;        }        else{            printf("Can not recognition!\n");        }    }    return 0;}

搜寻插入

int InsertSearch(struct number *phead){    unsigned short go = 0;    int temp;    char ch[5];    struct number *ptemp,*pnew,*pend;    ptemp = phead;    if(ptemp->next == NULL){        printf("Can not find any nodes!\n");        return -1;    }    printf("Please input the information you want to search.\n");    scanf("%d",&temp);    while(1){        while(1){            if(ptemp->next == NULL){                printf("Can not find the information!\n");                go = 1;                break;            }            ptemp = ptemp->next;            if(temp == ptemp->num){                printf("Is this the information you want?:%d (To input 'Y' to confirm.)\n",ptemp->num);                scanf("%s",ch);                if(strcmp(ch,"y") == 0||strcmp(ch,"Y") == 0){                    pend = ptemp->next;                    pnew = (struct number *)malloc(sizeof(struct number));                    ptemp->next = pnew;                    pnew->next = pend;                    printf("Please input a number!\n");                    scanf("%d",&pnew->num);                    go = 1;                    break;                }            }        }        if(go == 1){            break;        }    }    if(go == 0){        printf("Can not find the information you want!");    }    return 0;}

链表逆置:

int Reverse(struct number *phead){    if(phead->next == NULL){        printf("Can not find any nodes!\n");        return -1;    }    struct number *ptemp,*pend,*pchange1,*pchange2;    unsigned short i,j,len = 0,times;    ptemp = phead->next;    while(ptemp != NULL){        ptemp = ptemp->next;        len++;    }    if(len == 1){        return 0;    }    if(len == 2){        ptemp = phead->next;        phead->next = phead->next->next;        phead->next->next = ptemp;        ptemp->next = NULL;        return 0;    }    times = len/2;    for(i = 0;i < times;i++){        ptemp = phead;        for(j = 0;j < i;j++){            ptemp = ptemp->next;        }        pchange1 = ptemp;        ptemp = ptemp->next;        pend = phead;        for(j = 0;j < len;j++){            pend = pend->next;        }        pchange2 = phead;        for(j = 0;j <len - 1;j++){            pchange2 = pchange2->next;        }        len--;        pchange1->next = pend;        pchange1 = pend->next;        pend->next = ptemp->next;        pchange2->next = ptemp;        ptemp->next = pchange1;    }    return 0;}

搜寻链表

int Search(struct number *phead){    unsigned short go = 0;    int temp;    char ch[5];    struct number *ptemp;    ptemp = phead;    if(ptemp->next == NULL){        printf("Can not find any nodes!\n");        return -1;    }    printf("Please input the information you want to search.\n");    scanf("%d",&temp);    while(1){        while(1){            if(ptemp->next == NULL){                printf("Can not find the information!\n");                go = 1;                break;            }            ptemp = ptemp->next;            if(temp == ptemp->num){                printf("Is this the information you want?:%d (To input 'Y' to confirm.)\n",ptemp->num);                scanf("%s",ch);                if(strcmp(ch,"y") == 0||strcmp(ch,"Y") == 0){                    go = 1;                    break;                }            }        }        if(go == 1){            break;        }    }    if(go == 0){        printf("Can not find the information you want!");    }    return 0;}

销毁链表

int Destory(struct number *phead){    struct number *ptemp,*pend;    if(phead->next == NULL){        printf("Can not find any nodes!\n");        return -1;    }    ptemp = phead->next;    pend = ptemp->next;    phead->next = NULL;    while(pend != NULL){        free(ptemp);        ptemp = pend;        pend = pend->next;    }    free(ptemp);    free(pend);    return 0;}

在此将数据结构与算法概述第一次讲座的主要内容都已经加以总结,由于鄙人理解能力有限,难免有理解不到位和出错的地方,希望谅解,如有意见或者发现文中有错误的地方,欢迎指正。

PS:给大家推荐一个网站:http://visualgo.net/,这个网站对各种数据结构和算法都有很好的可视化表述,能很好的帮助我们理解难懂的数据结构和算法。

1 0