1 数据结构1----数据结构知识框架

来源:互联网 发布:斗牛怎么快速算点数js 编辑:程序博客网 时间:2024/04/28 03:32

原文链接:http://wenku.baidu.com/link?url=PvdCzxVyIx_zHnBDJrsJkPyj7vf1XoSvvWJw357lqrtEu-Vi_mogun6aMi2IsSZUrSulTG6z28dPzmGHPBGXfQnio_67tErIIVlVFwLRvpe

数据结构复习提纲 1

第一章 绪论 1

数据结构研究内容:逻辑结构,存储结构,算法 1

 基本概念 1

算法和算法分析 2

第二章 线性表 2

第三章 栈和队列 5

第四章 数组 8

第五章 树和二叉树 8

第六章  11

第七章 查找 12

第八章排序 13

第九章数据结构的一般应用 15

 

数据结构复习提纲

第一章 绪论

数据结构研究内容:逻辑结构,存储结构,算法

   数据的逻辑结构,也就是数据元素之间的逻辑关系。数据的逻辑结构可以分为集合(无关系)、线性结构1:1)、树型结构(1:N)、图型结构(N:M)。

数据的存储结构:数据及其逻辑结构在存储器中的存储方式,一般的有顺序存储,链式存储,索引存储,散列存储。

   数据操作:在数据的各种结构(逻辑和物理)上实施有效的操作,主要包括:查找,插入,删除,修改,排序,分析等。

   数据结构研究的一般是用计算机解决的大数据量的问题。

二 基本概念

1.数据:可以被计算机识别,存储和加工处理的符号的总称。

2.数据元素:数据的基本单位,有时,一个数据元素可由若干个数据项组成。

3.数据项:数据不可分割的最小单位。

4.数据对象:性质相同的数据元素的集合,是数据的一个子集

5.数据类型: 用于限定数据取值范围(与存储形式有关)和可能进行的操作(运算)的总和.   

6.数据结构的数学描述:B=(D,R)

   其中:D是数据元素的集合;

       R是D上所有数据元素之间关系的有限集合,

反映了各元素的前驱、后继关系。

算法和算法分析

1.算法:由有限条指令组成,规定了(计算机)解决特定问题的一系列操作。

2.算法特性:算法具有正确性、有穷性,确定性,(可行性)、输入,输出

正确性:能按设计要求解决具体问题,并得到正确的结果。

有穷性:任何一条指令都只能执行有限次,即算法必须在执行有限步后结束。

确定性:算法中每条指令的含义必须明确,不允许由二义性

可行性:算法中待执行的操作都十分基本,算法应该在有限时间内执行完毕。

输入:一个算法的输入可以包含零个或多个数据。

输出:算法有一个或多个输出

3.算法分析(一个好得法应达到的目标)

   1)正  确 性:算法应能满足设定的功能和要求 。

   2)可  读 性:思路清晰、层次分明、易读易懂 。

   3)健  壮 性:输入非法数据时应能作适当的反应和处理。

   4)高  效 性(时间复杂度):解决问题时间越短,算法的效率就越高。  

   5)低存储量(空间复杂度):完成同一功能,占用存储空间应尽可能少。

4.时间复杂度:T(n)        数量级O(f(n))

  空间复杂度:S(n)              O(f(n))   n为问题规模

第二章 线性表

1. 线性表定义:线性表(Linear List)是一种线性数据结构,其特点是数据元素之间存在“一对一”的关系。

2. 线性表的基本操作:初始化、求表长、取表元、按值查找、插入、删除

3. 线性表的顺序存储和C语言描述(PPT)

顺序表的概念:线性表的顺序存储是指在用一组地址连续的存储单元依次存储线性表的数据元素,我们把用这种存储形式存储的线性表称为顺序表。顺序表的逻辑顺序和物理顺序是一致的。如图

顺序表的C语言描述(1)在程序设计语言中,一维数组在内存中占用的存储空间,就是一组连续的存储区域,可以用一维数组来表示:

        #define  MAXLEN   n

datatype  data[MAXLEN];    

                         int  last;

     2)从结构性上考虑,常将data和last封装成一个结构作为

       顺序表的类型:

                          typedef  struct

                          { datatype  data[MAXLEN];

                            int  last;

                           }SeqList;

 

4. 顺序存储的线性表按值查找、插入、删除操作的C语言程序(PPT)

按值查找:指在线性表中查找与给定值x相等的数据元素。

   具体算法:int  Locate ( SeqList  L , datatype  x )

            { int  i ;

              i=1 ;

              while (L.data [ i ] != x && i <= L.last )

                        i + + ;

               if ( i > L.last )  return (-1);

              else  return   i ;}

插入操作:指在表的第i个位置上插入一个值为x的新元素,插入后使原表长为n的表,成为表长为n+1的表。


#define  maxlen  100

typedef  struct

{ char  data[MAXLEN];

    int  last;

          }SeqList;

    Void main(){

       seqlist  L;

       L.last=3

       L.data={ ‘a’,’b’,’c’};

       Char x=‘d’;

      inslist(L, 2,  x)

}


具体算法:

Seqlist  InsList(SeqList  L , int  i , char  x)

        {int  j ;

          if (L.last ==MAXLEN-1)

              {printf (“Overflow ! \n”) ;

                    exit ( );}

           if ((i < 1) || (i > L.last+1))  

              {printf (“Position  does  not  exit ! \n”) ;

               exit ( ) ;}

或   if (i<1) i=1;

            if (i>L.last) i=L.list

           for ( j = L.last ; j >= i ; j- -)

                  L.data [ j + 1 ] = L.data [ j ] ;         

           L.data [ i ] = x ;

           L.last = L.last + 1 ;

         return L}

删除操作:指将表中第i个元素从线性表中去掉,删除后使原表长为n的线性表。

具体算法:

           void  DelList ( SeqList  L, int  i )

                    { int  j ;

                       if (( i<1 ) || ( i>L.last ))

                       printf(“Position  does  not  exit ! \n”) ;

                       else

   { for ( j = i + 1 ; j <= L.last ; j + + )

                                     L.data [ j-1 ] = L.data [ j ] ;

                              L.last=L.last-1;

                            }

                      }

5. 线性表的链式(单链表,双向链表)存储和C语言描述(PPT)

6. 为何? 顺序->单链表->循环链表->双向循环链表

7. 链式存储的线性表初始化(由顺序表)、按值查找、插入、删除操作的C语言程序(PPT)

       1、求表长

          int  LenList1 ( LinkList  H )          /*带头结点的线性链表*/

          { int  n =0 ;    LinkList  p = H ;

            while ( p -> next != NULL )    { p=p->next ;  n + + ; }  //  dosomething(p)

            return  n ; }

int  LenList2 ( LinkList  H )       /*不带头结点的线性链表*/

          { int  n ;      LinkList  p = H ;

            if (p==NULL)  return  0 ;   n=1;

            while ( p -> next ) { p = p -> next ; n + + ; }  return  n ;}

 2、序号查找

          LinkList  SearchList ( LinkList  L , int  i )          /* 带头结点的线性链表 */

          { LinkList  p = L ;     int  j = 0 ;

          while ( p -> next != NULL && j < i )   { p = p -> next ;     j + + ; }

            if ( j == i)        return  p ;      else       return  NULL ; }

3、值查找

           LinkList  LocateList ( LinkList  L , datatype  x )       /* 带头结点的线性链表 */

            { LinkList  p = L -> next ;  

            while ( p != NULL && p -> data != x )       p = p -> next ;}

 4、插入

1)后插结点

void  inster ( LinkList  L , LinkList  p , datatype  x )

 { LinkList  s ;       s = ( LinkList ) malloc ( LEN ) ;      s -> data = x ;  

 s -> next = p -> next ;      p -> next = s ;    }

              在第三个节点后加入”A”              inster( head, searchlist( head,3), “A”)

2)前插结点          /*带头结点的线性链表*/

           void  insert ( LinkList  L , LinkList  p ,datatype  x )

           { LinkList  s , q ;    s = ( LinkList ) malloc ( LEN ) ;      s -> data = x ;     q = L ;

           while ( q -> next != p)   q = q -> next ;       s -> next = p ;    q -> next = s ; }

5、删除

void  delete ( LinkList  L , LinkList  p )

        { LinkList  q ;          q = L ;

        while ( q -> next != p )      q = q -> next ;   q ->next = p -> next ;   free ( p ) ;}

         delete(head, locatelist( head,” ”) )

6、建立线性链表

1)在链表的头部插入结点建立线性链表

LinkList CreateList (     )

 { LinkList  head , s ;   datatype  x ;   head == NULL ; scanf ( “%c” , &x ) ;   //读数据x=scanfdata( ) ;

while ( x != ‘#’ )      //结束

         { s = ( LinkList ) malloc ( LEN ) ;    s -> data = x ;   s -> next = head ;

              head = s ;       scanf ( “%c” , &x ) ; //读数据x=scanfdata( ) ;  }

           return  head ;}

2)在链表的尾部插入结点建立线性链表

LinkList  CreateList ( )

            { LinkList  head , s , p ;   char  c ;    scanf (“%c”, &x );   head = NULL ;   p = head ;

              while ( x != ‘#’)    { s = ( LinkList ) malloc ( LEN ) ;     s -> data = x ;

                              if ( head == NULL)   head = s;  else   p -> next = s ;

  p = s ; }

              p -> next =NULL ;     return  head ;  }   

8. 链式存储的存储密度在d=数据结点存储量/整个节点的存储量

第三章 栈和队列 

1. 栈的定义FILO):是限制在表尾进行插入和删除的线性表。

2. 顺序栈的C语言描述:

    1)用一维数组实现顺序栈

#define  MAXLEN  n         // 分配最大的栈空间

        char  s[MAXLEN];       // 数据类型为字符型

        int  top;              // 定义栈顶指针

用结构体数组实现顺序栈

 顺序栈的结构体描述:

        #define  MAXLEN  10             // 分配最大的栈空间

   typedef  struct                          // 定义结构体

   { datatype  data[MAXLEN]; // 定义存放栈元素的数组

     int  top;                              // 定义栈顶指针

   } SeqStack;

 再定义一个指向顺序栈的指针:

 SeqStack  *S;                // 定义S为结构体类型的指针变量

3. 顺序栈的操作:出栈、入栈

 

4. 栈的应用 :中缀表达式转换为后缀表达式

 

5. 队列的定义FIFO)是限制在表尾进行插入和在表头进行删除的。

6. 顺序队列,溢出

顺序队列是用内存中一组连续的存储单元顺序存放队列中各元素。

 

7. 链队列的C语言描述

 

8. 链队列的操作:入队、出队C语言描述

 

9. 优先队列:多个队列,优先级高的队列尾作为优先级低的队列头的前驱

第四章 数组

1、 串的定义(String) :是由零个或多个任意字符组成的有限序列。

2、 模式匹配:即子串定位运算。设s和t是给定的两个串,在主串s中找到等于子串t的过程称为模式匹配。其中被匹配的主串s称为目标串,匹配的子串t称为模式。

3、 数组:同一数据类型的一组数据,是线性表的一扩展形式。

4、 稀疏矩阵的压缩存储:三元组存储法

 第五章 树和二叉树

1. 树的定义

   树(Tree):是 n(n≥0)个有限数据元素的集合。

      在任意一棵非空树T中:

     1)有且仅有一个特定的称为树根(Root)的结点,根结点无前趋结点;

     2)当n>1时,除根结点之外的其余结点被分成m(m>0)个互不相交的集合T1,T2,…,Tm,其中每一个集合Ti(1≤ i ≤m)本身又是一棵树,并且称为根的子树。

2. 基本术语:

结点的度数:结点的非空子树(即后缀)个数叫作结点的度数

树叶、分支结点:左(右)子树均为空二叉树的结点称作树叶否则称作分支结点。

结点的层数:规定根的层数是0,其余结点的层数等于其父结点的层数加1

孩子和双亲:

树的深度:

树的度数:树中度数最大的结点度数叫作树的度数

树林:是由零个或多个不相交的树所组成的集合。

3. 二叉树的定义:

二叉树是有n(n>=0)个结点的有限集合。

1)该集合或者为空(n=0);

2)或者由一个根结点及两个不相交的分别称为左子树和右子树组成的非空树;

3)左子树和右子树同样又都是二叉树。

通俗地讲:在一棵非空的二叉树中,每个结点至多只有两棵子树,分别称为左子树和右子树,且左右子树的次序不能任意交换。所以,二叉树是特殊的有序树。

4. 满二叉树和完全二叉树:

 

5. 二叉树的性质:

1) 一棵非空二叉树的第i层上最多有2i–1个结点(i≥1)

2) 深度为h的二叉树中,最多具有2h1个结点(h≥1)

3) 具有n(n>0)个结点的完全二叉树(包括满二叉树)的深度(h)为:log2n +1

4) 对于一棵非空的二叉树,设n0、n1、n2分别表示度为0、1、2的结点个数, 则有:  n0=n2+1。

6. 二叉树的顺序存储:

 

7. 二叉树的二叉链存储、三叉链存储 C语言描述

 

 

8. 遍历二叉树(先序DLR、中序LDR、后序LRD)方法与C语言描述

由二叉树的递归定义可知,一棵二叉树由根结点(D)、根结点的左子树(L)和根结点的右子树(R)三部分组成。因此,只要依次遍历这三部分,就可以遍历整个二叉树。一般有三种方法:先序(前序)遍历DLR(根左右)、中序遍历LDR(左根右)、 后序遍历LRD(左右根)。

 

9. 标识符树及其生成(PPT)

    将算术表达式用二叉树来表示,称为标识符树,也称为二叉表示树。

10. 哈夫曼树:叶子结点带有权值的最小带权路径长度的最优二叉树

 

11. 哈夫曼树的生成方法:(PPT)

12. 哈夫曼编码:在哈夫曼树中把从每个节点引向其左子节点的边标上二进制数“0”,把从每个节点引向右子节点的边标上二进制数“1”,从根到每个叶节点的路径上的二进制数连接起来,就是这个叶节点所代表字符的最优前缀编码。常把这种编码称为哈夫曼编码

第六章 

1. 图的定义:图(Graph)是一种比树形结构更复杂的非线性结构。在图形结构中,每个结点都可以有多个直接前驱和多个直接后继。

2. 术语:无向图、有向图、顶点、弧、顶点的度、出度、入度、边的权、

路径、路径长度、回路、连通图

无向图:图中每条边都是无方向的,则成为无向图

有向图:图中每条边都是有方向的,则称为有向图

顶点:

弧:

顶点的度、出度、入度:与顶点v相关联的边数称为顶点的度,记为D(v)。若G是一个有向图,则以顶点v为终点的边的数目成为v的入度,记为ID(v);以v为始点的边的数目称为v的出度,记为OD(v),有向图中顶点v的度为其入度和出度之和,即D(v)=ID(v)+OD(v)

边的权:图的边或弧有时具有与它有关的数据信息,这个数据信息就称为权

路径:

路径长度:路径上的边数

回路:起点和终点相同的简单路径称为回路或环

连通图:若V(G)中任意两个不同的顶点vi和vj都是连同的(即有路径),则称G为连通图。

3. 图的存储:邻接矩阵

邻接表

4. 图的遍历:深度遍历、广度遍历

5. 无向图的最小生成树Prim算法

6. 最短路径Dijkkstra算法

第七章 查找

1. 基本概念:关键码(KEY)、平均查找长度(ASL)

2. 顺序查找:顺序查找又称线性查找,是最基本的查找方法之一。顺序查找既适用于顺序表,也适用于链表。

    int SeqSearch(dataType a[ ],int n)  // 顺序查找

    { int i=n-1;

      while (i>=0&&a[i]!=a[0])   //从后向前比较        i--;

      if (i==0)    return 0 ;    else    return   i ;

      }

Void Main( )

{  int  a[10]={-1,34,54,65,64,35,74,63,43,,86};    int  find=0;

     printf("请输入要查找的数据:");

     scanf(“%d”,&a[0]) ;   //a[0]为监测哨

       find=SeqSearch(a,10, k)

       if find then printf ("已找到,在第%d的位置上\n",find);

        else Printf ("没有找到\n");  

}

3. 二分法(折半)查找:是一种效率较高的查找方法,但前提是表中元素必须按关键字有序(按关键字递增或递减)排列。

    Void Main( )

{  int  a[10]={-1,18,24,34,47,51,65,74,78,86};  //有序

       int  find=0;

      printf("请输入要查找的数据:");

     scanf(“%d”,&a[0]) ;   //a[0]为监测哨

       find=BinSearch(a,10)

       if find then printf ("已找到,在第%d的位置上\n",find);

        else Printf ("没有找到\n");  }

void BinSearch(DataType a[],int n) //二分查找

{ int i,k,low,mid,high;   low=1;high=n-1;m=0;

     while(low<=high)

    { mid=(low+high)/2;    m++;

      if(a[mid]>a[0]) high=mid-1;

         else   if (a[mid]<a[0])      low=mid+1;      else break;     //找到了

        }

   If(low>high)    return 0;    else   return mid+1;}

4. 分块查找:块内无序、块间有序、如何分块效率最高

5. 二叉排序树查找:二叉排序树的生成

6. 哈希表:哈希函数构造:直接定址法、除留余数法、平方取中法

冲突解决方法:开放定址法、拉链法、公共溢出区法

7. 各种查找算法的ASL计算与效率比较

第八章排序

1. 内部排序与外部排序   

内部排序整个排序过程都在内存进行的排序称为内排序。

外部排序:待排序的数据元素量大,以致内存一次不能容纳全部记录,在排序过程中需要对外存进行访问的排序称为外排序

2. 插入排序.

  void Insertsort()

 { for(i=2;i<=L;i++)        // 依次插入r[2],r[3],……r[n]

   {if (R[i].key<R[i-1].key)

      { R[0]=R[i];                // 置监视哨

        j=i-1;

        while(R[0].key<R[j].key)  // 查找r[i]的位置

        { R[j+1]=R[j];            // 向后移动记录

          j- -;

         }

  R[j+1]=R[0];              // 插入r[i]

      }

    }

 }

3. 冒泡排序:冒泡法也称沉底法,每相邻两个记录关键字比大小,大的记录往下沉(也可以小的往上浮)。每一遍把最后一个下沉的位置记下,下一遍只需检查比较到此为止;到所有记录都不发生下沉时,整个过程结束(每交换一次,记录减少一个反序数)。

        void Bubblesort()

{ for(i=1;i<L;i++)

         { for(j=L;j>=i+1;j--)

            if (R[j].key<R[j-1].key)            // 小则交换

             { R[0].key=R[j].key;

               R[j].key=R[j-1].key;

                R[j-1].key=R[0].key;

                  }

             }

         }

 

4. 选择排序

       void Selectsort()

  { for (i=1;i<n;i++)

{ h=i;     

 for (j=i+1;j<=n;j++)

         if (R[j].key<R[h].key)       // 选择关键字值最小的记录           h=j;

    if (h!=j)         { R[0]=R[i];R[i]=R[h];R[h]=R[0];}     //交换记录

   }

 }

5. 快速排序.

      int Partition( int i,int j ) //ij为形参,分别代表lowhigh

 { RecType pivot=R[i];

    while(i<j)        // 从表的两端交替地向中间扫描

    { while(i<j&&R[j].key>=pivot.key)         j- -;

       if (i<j)       R[i++]=R[j];

      while (i<j&&R[i].key<=pivot.key)        i+ +;

       if (i<j)     R[j- -]=R[i];

   }  

    R[i]=pivot; return i;

 }

 void QuickSort( int low,int high)         // 递归形式的快排序

{ int pivotpos,k;

  if (low<high)       { pivotpos=Partition( low,high);     //调用Partition(low,high)函数

                             QuickSort(low,pivotpos-1);          // 对低子表递归排序

                             QuickSort(pivotpos+1,high);          // 对高子表递归排序

                            }

 }

6. 归并排序.

 void Merge (int low,int mm,int high)       // 两个相邻有序段的合并

  { RecType  *R1;

    while(i<=mm&&j<=high)

    R1[p++]=(R[i].key<=R[j].key)?R[i++]:R[j++];

    while(i<=mm)

  R1[p++]=R[i++];

    while(j<=high)

  R1[p++]=R[j++];

    for(p=0,i=low;i<=high;p++,i++)   

   R[i]=R1[p];

 }

void MergePass(int length)   

 // 完成一趟完整的合并

  { for (i=1;i+2*length-1<=L;i=i+2*length)      Merge(i,i+length-1,i+2*length-1);

     if (i+length-1<L)        Merge(i,i+length-1,L);

 }

   void Mergesort()            // 控制有序段的长度,每合并一趟,有序段长加倍

 { for (length=1;length<L;length*=2)

       { MergePass(length);    m++;       }

 }

7. 基数排序.

8. 各种排序方法比较.

(1)排序是将数据的任意序列,重新排列成一个按关键字有序的序列。

(2)整个排序过程全部在内存进行的排序称为内排序,直接插入排序、希尔排序、冒泡排序、快速排序、简单选择排序、堆排序一般适合内排序。归并排序既适合内排序,也适合外排序。

(3)若对任意的数据元素序列,使用某个排序方法,对它按关键字进行排序,若相同关键字元素间的位置关系,排序前与排序后保持一致,称此排序方法是稳定的;反之,则称为不稳定的。

(4)直接插入排序、冒泡排序、归并排序是稳定的排序方法;而简单选择排序、希尔排序、快速排序、堆排序是不稳定的排序方法。 

(5)直接插入排序、冒泡排序、简单选择排序是简单型的排序,其时间复杂度都为O(n 2),空间复杂度为O(1)。

(6)堆排序、快速排序和归并排序是改进型的排序方法,其时间复杂度均为O(nlog2n),空间复杂度分别为:O(1)、O(log2n)、O(n)。

(7)希尔排序又称为缩小增量排序,也是插入类排序的方法,但在时间上有较大的改进。其时间复杂度约为:O(n1.3),空间复杂度为:O(1)。

(8)各种不同的排序方法应根据不同的环境及条件分别选择。一般而言,对于排序元素少的,可以选用时间复杂度为O(n2)的算法;对于元素多的,可选用时间复杂度为:O(nlog2n)的算法。 

第九章数据结构的一般应用

 

0 0
原创粉丝点击