zoukankan      html  css  js  c++  java
  • 数据结构入门第二课(浙大mooc笔记)

    数据结构入门第二课

    引子 多项式的表示

    方法1 顺序结构表示多项式各项

    数组各分量对应多项式各项

    问题:可能造成空间浪费

    方法2 顺序结构表示非零项

    将一个多项式看成系数和指数的二元组合,用结构数组表示:数组分量是由指数系数组成的结构,对应一个非零项。

    要点:按指数大小有序存储

    方法3 链表结构存储非零项

    链表中每个结点存储多项式中的一个非零项,包括系数和指数两个数据域以及一个指针域。

    typeof struct PolyNode* Polynomial;
    struct PolyNode{
    	int coef;
    	int expon;
    	Polynomial link;
    }
    

    多项式问题的启示

    同一个问题可以有不同的表示(存储)方法;

    有一类共性问题:有序线性序列的组织和管理;

    线性表

    线性表:由同类型数据元素构成有序序列的线性结构

    ​ 表中元素个数称为线性表的长度;

    ​ 线性表中没有元素时,称为空表;

    ​ 表起始位置称为表头,表结束位置称为表尾;

    线性表的抽象数据类型描述

    image.png

    线性表的顺序存储实现

    利用数组的连续存储空间顺序存放线性表的各元素

    image.png

    主要操作的实现

    1. 初始化(建立空的顺序表)
      /* 初始化 */
      List MakeEmpty()
      {
          List L;
       
          PtrL = (List)malloc(sizeof(struct LNode));
          L->Last = -1;
       
          return PtrL;
      }
      
    2. 查找
      /* 查找 */
      #define ERROR -1
       
      Position Find( List L, ElementType X )
      {
          int i = 0;
       
          while( i <= L->Last && L->Data[i]!= X )
              i++;
          if ( i > L->Last )  return ERROR; /* 如果没找到,返回错误信息 */
          else  return i;  /* 找到后返回的是存储位置 */
      }
      
    3. 插入(第i个位置)
      /* 插入 */
      bool Insert( List L, ElementType X, int P ) 
      { /* 在L的指定位置P前插入一个新元素X */
          int i;
       
          if ( L->Last == MAXSIZE-1) {
              /* 表空间已满,不能插入 */
              printf("表满"); 
              return false; 
          }  
          if ( P<0 || P>L->Last+1 ) { /* 检查插入位置的合法性 */
              printf("位置不合法");
              return false; 
          } 
          for( i=L->Last; i>=P; i-- )
              L->Data[i+1] = L->Data[i]; /* 将位置P及以后的元素顺序向后移动 */
          L->Data[P] = X;  /* 新元素插入 */
          L->Last++;       /* Last仍指向最后元素 */
          return true; 
      } 
      
    4. 删除(第i个位置)
      /* 删除 */
      bool Delete( List L, int P )
      { /* 从L中删除指定位置P的元素 */
          int i;
       
          if( P<0 || P>L->Last ) { /* 检查空表及删除位置的合法性 */
              printf("位置%d不存在元素", P ); 
              return false; 
          }
          for( i=P+1; i<=L->Last; i++ )
              L->Data[i-1] = L->Data[i]; /* 将位置P+1及以后的元素顺序向前移动 */
          L->Last--; /* Last仍指向最后元素 */
          return true;   
      }
      

    线性表的链式存储实现

    不要求逻辑上相邻的两个元素物理上也相邻;通过链建立起数据元素之间的逻辑关系。

    插入输出不需要移动数据元素,只需要修改链。

    typedef struct LNode *PtrToLNode;
    struct LNode {
        ElementType Data;
        PtrToLNode Next;
    };
    typedef PtrToLNode Position;
    typedef PtrToLNode List;
    

    主要操作的实现

    1. 求表长
    int length(List PtrL){
    	List p=PtrL;//指向表的第一个结点
    	int j=0;
    	while(p){
    		p=p->Next;
    		j++;
    	}
    	return j;
    }
    
    1. 查找
      • 按序号查找(FindKth)
        List FindKth(List L, int K)
        {
            List p = PtrL; /* p指向L的第1个结点 */
        	while ( p!=Null && i<K ){
            	p = p->Next;
            	i++;
            }
            if(i==K)return P;
            else
                return NULL;
        } 
        
      • 按值查找
        Position Find( List L, ElementType X )
        {
            Position p = L; /* p指向L的第1个结点 */
         
            while ( p && p->Data!=X )
                p = p->Next;
         
            /* 下列语句可以用 return p; 替换 */
            if ( p )
                return p;
            else
                return ERROR;
        }
        
    2. 插入
      image.png
    /* 带头结点的插入 */
    bool Insert( List L, ElementType X, Position P )
    { /* 这里默认L有头结点 */
        Position tmp, pre;
     
        /* 查找P的前一个结点(可用p=Find(Ptrl,x);代替 */        
        for ( pre=L; pre&&pre->Next!=P; pre=pre->Next ) ;            
        if ( pre==NULL ) { /* P所指的结点不在L中 */
            printf("插入位置参数错误
    ");
            return false;
        }
        else { /* 找到了P的前一个结点pre */
            /* 在P前插入新结点 */
            tmp = (Position)malloc(sizeof(struct LNode)); /* 申请、填装结点 */
            tmp->Data = X; 
            tmp->Next = P;
            pre->Next = tmp;
            return true;
        }
    }
    
    1. 删除
    image.png
    /* 不带头结点的删除,第i位置*/
    List Delete( List L, int i )
    { /* 这里默认L有头结点 */
        List p,s;
     	if (i==1){//删除头结点的情况
     	S=PtrL;
     	if(PtrL!=NULL)PtrL=PtrL->Next;
     	else 
     		return NULL;
     	free(s);
     	return PtrL;
     	}
      	p=FindKth(i-1,PtrL);/*查找i-1个结点*/
      	if(p==NULL){
      		printf("the %d node is not exist",i-1);
      		return NULL;
      	}else if(p->Next==NULL){
      		printf("the %d node is not exist",i-1);
      		return NULL; 		
      	}else{
      		s=p->Next;
            p->Next=s->Next;
            free(s);
            return PtrL;
      	}
    }
    

    广义表

    image.png image.png

    多重链表

    image.png image.png image.png image.png
  • 相关阅读:
    安装的时候,突然安装程序关闭,的灵异问题。
    CSAPP阅读笔记(1)-序
    CSAPP阅读笔记(2)-虚存管理
    nafxcwd.lib(afxmem.obj) :error LNK2005:"void * __cdecl operator new(unsigned int)"
    Linux内核源代码情景分析读书笔记(5)-关于fork/clone/vfork
    [转]调试经验总结VC下的错误对话框
    IP数据包首部的校验和算法
    Matlab画图及生成exe文件
    VC++6.0中的new
    Linux内核模块编译、加载&卸载及查看运行结果
  • 原文地址:https://www.cnblogs.com/yiyefuyou/p/12810152.html
Copyright © 2011-2022 走看看