zoukankan      html  css  js  c++  java
  • 线性表 顺序链式实现

    线性表 顺序存储实现

    (1)如何存储

    //如何存储
    typedef struct
    {
        ElementType Data[MAXSIZE];
        int Last;
    }List;
    List L, *PtrL;

    访问下标为i的元素:L.Data[i] 或 PtrL->Data[i]

    线性表的长度:L.Last+1 或者 PtrL->Last+1

    (2)初始化(建立空的顺序表)

    List *MakeEmpty()
    {
        List *PtrL;
        PtrL = (List *)malloc(sizeof(List));
        PtrL->Last = -1;
        return PtrL;
    }
    

    (3)查找

    int Find(ElementType X, List *PtrL)
    {
        int i = 0;
        while(i<=PtrL->Last && PtrL->Data[i]!=X)
            i++;
        if (i > PtrL->Last)
            return -1;
        else
            return i;
    }
    

    查找成功的平均比较次数为(n+1)/ 2(第一次比较就找到或者最后一次比较才找到),平均时间性能为O(n)。

    (4)插入

    插入到第 i 个位置(即下标+1:1<=i<=n+1)上插入一个值为X的新元素)

    //插入
    void Insert(ElementType X, int i, List *PtrL){
        if (PtrL->Last == MAXSIZE-1){
            printf("表满");
            return;
        }
        if (i < 1 || PtrL->Last+2){
            printf("位置不合法");
            return;
        }
        for (int j = PtrL->Last; j >= i-1; --j){
            PtrL->Data[j+1] = PtrL->Data[j]; //将 an~a1 依次向后移动一位
        }  
        PtrL->Data[i-1] = X;//插入新元素
        PtrL->Last++; //Last仍指向最后元素
    return;
    }

    平均移动次数为n/2,平均时间性能为O(n)。

    (5)删除

    //删除
    void Delete(int i, List *PtrL){
        if (i < 1 || i > PtrL->Last+1){
            printf("不存在第 %d 个元素", i );
            return;
        }
        for (j = i; j <= PtrL->Last; ++j){
            PtrL->Data[j-1] = PtrL->Data[j]; //将ai+1~an顺序向前移动
        }
        PtrL->Last--;
        return;
    }
    

    平均移动次数为(n-1)/2,平均时间性能为O(n)。

    线性表 链式存储实现

    基本操作

    Node* applyNode();   //分配节点
    Node* addNodeH(Node* Head,Node* InsertNode);       //在头部添加节点
    Node* addNodeT(Node* Head,Node* InsertNode);       //在尾部添加节点
    Node* addNodeSort(Node* Head, Node* InsertNode);   //以升序方式添加节点

    Node* createList(int n,int choose);   //构造链表
    void printList(Node*Head);            //打印链表
    void freeList(Node*& Head);           //释放链表
    int numOfNodes(Node* Head);           //求表长(节点数)

    Node* locateNodeI(Node*Head,int i);   //定位
    int SearchList(Node*Head,int value);    //查找
    bool insertNodeI(Node* Head, int i);     //插入
    bool deleteNodeI(Node*&Head,int i);   //删除
    void sortList(Node*& Head);              //排序

    1、构造节点

    //定义节点类型

    struct Node{
        int value;
        Node*next;
    };

    2、分配节点

    //将分配内存和初始化该节点放在一个函数中
    Node* applyNode(){
      Node* newNode;
      if( ( newNode = (Node*)malloc(sizeof(Node)) )==NULL ){
        cout << "分配内存失败!" << endl;
        exit(0);
      }
      cin >> newNode->value;
      newNode->next = NULL;
      return newNode;
    }

    3、在头部添加节点

    Node* addNodeH(Node* Head){  
       Node* InsertNode = applyNode();
       if(Head==NULL)
          Head = InsertNode;
       else{
          InsertNode->next = NULL;
          Head->next = InsertNode;
       }
       return Head;
    }

    4、在尾部添加节点

    Node* addNodeT(Node* Head){
       Node* InsertNode = applyNode();
       if(Head==NULL)
          Head=InsertNode;
       else{
          Node* p=Head;
          while(p->next!=NULL)
             p=p->next;
          p->next = InsertNode;
       }
       return Head;
    }

    5、以升序方式添加节点

    Node* addNodeSort(Node* Head){
       Node* InsertNode = applyNode(); //分配节点
       if(Head==NULL){
          Head=InsertNode;
       }
       else{
          Node* p=Head;
          while( (p->value)<(InsertNode->value) && p->next!=NULL )
             p=p->next;
          if( (p->value)>=(InsertNode->value)){
             InsertNode->next = p->next; //先在p后增加节点
             p->next = InsertNode;
             swap(p->value, InsertNode->value); //再交换p和InsertNode的value值
          }
          else{   //因为(p->next==NULL)而退出循环!表示在尾部增加节点
             p->next = InsertNode;
          }
       }
       return Head;
    }

    6、构造链表

    //建立n个节点的链表
    //choose=0:在表头加入;  choose=1:在表尾加入;  choose=2:按value值升序加入
    Node* createList(int n, int choose){
       Node *Head=NULL, *p=NULL;
       for(int i=0; i<n; i++){
            p = applyNode(); //分配节点
            cin >> choose;
            switch(choose){
            case 0:
                 Head = addNodeH(Head, p); //头插
                 break;
            case 1:
                 Head = addNodeT(Head, p); //尾插
                 break;
            case 2:
                 Head = addNodeSort(Head, p); //升序插
                 break;
            default:
                 printf("default");
                 break;
       }
       return Head;
    }

    7、打印链表

    //遍历链表并输出
    void printList(Node* Head){
       Node* p=Head;
       while(p!=NULL){
          cout << p->value << "->";
          p=p->next;
       }
       cout << "NULL" << endl;
    }

    8、释放链表

    void freeList(Node* Head){
       Node* tmp=Head;
       while(tmp!=NULL){
          Head = Head->next;
          free(tmp);
          tmp = Head;
       }
       Head=NULL; 
    }

    9、求表长(节点数)

    //求节点个数
    int numOfNodes(Node* Head){     
       Node* temp = Head;
       int count=0;
       while(temp!=NULL){
          count++;
          temp=temp->next;
       }
       return count;
    }

    10、定位

    //定位(指向)第i个节点,i从1开始
    Node* locateNodeI(Node* Head, int i){
       Node* pos=NULL;
       int count = numOfNodes(Head);
       if(i<=0 || i>count){
          cout << "定位越界!" << endl;
       }
       else {
          pos=Head;
          for(int j=1; j<i; j++)
              pos=pos->next;
       }
       return pos;
    }

    11、查找

    1)按照序号查找:FindKth

    List *FindKth(int K, List *PtrL){
        List *p = PtrL;
        int i = 1;
        while(p!=NULL && i< k){
            p = p->Next;
            i++;
        }
        if (i==k)
            return p; //找到第K个,返回指针
        else
            return NULL;
    }

    2)按照值查找:Find

    List *Find(ElementType X, List *PtrL){
        List *p = PtrL;
        while(p!=NULL && p->Data!=X)
            p = p->Next;
        return p;
    }

    3)按照值查找,返回其序号:SearchList

    //查找值value并返回第一个出现该值的位置
    //如果需要引用其指针,可以再locate该位置
    int SearchList(Node* Head, int value){
       Node* p=Head;
       int pos=0;
       bool find=false;
       while(p!=NULL){
          pos++;
          if(p->value==value){
             find=true;
             break;
          }
          p=p->next;
       }
       if(find)
          return pos;
       else 
          return -1;
    }

    12、插入

    //新节点插入到某位置i
    bool insertNodeI(Node* Head, int i){
       Node* s = applyNode();
       if(i==1){   //新节点插入在表头
          s->next = Head;
          Head = s;
          return true;
       }
       Node* p = locateNodeI(Head, i-1);
       if(p==NULL){
          return false;
       }
       else{
          s->next = p->next;
          p->next = s;
          return true;
       }
    }

    13、删 除

    //删除某位置i的节点
    bool deleteNodeI(Node* Head, int i){
       Node* s = locateNodeI(Head, i);
       if(s==NULL){
          return false;
       }
       else{
          if(s==Head){   //要删除的是头节点
             Head = s->next;
             free(s);
          }
          else{
             Node* p = locateNodeI(Head, i-1); //定位前一个节点,必定存在
             p->next = s->next;
             free(s);
          }
          return true;
       }
    }

    14、排序

    //链表排序
    //方法:只进行value的交换,不破坏链表结构
    void sortList(Node* Head){
       int count = numOfNodes(Head);
       if(count==0 || count==1)
          return ;
       //冒泡排序
       bool exchange;
       for(int i=2; i<=count; i++){   
          exchange=false;
          for(int j=count;j>=i; j--){
             Node* p1 = locateNodeI(Head, j);
             Node* p2 = locateNodeI(Head, j-1);
             if(p1->value < p2->value){
                exchange=true;
                swap(p1->value, p2->value); //交换数据
             }
          }
          if(!exchange)
             break;
       }
    }
    
  • 相关阅读:
    Oracle FGA审计记录的清理步骤
    UVa11488-Hyper Prefix Sets(trie树)
    配置Log4j(非常具体)
    poj1190生日蛋糕
    zju1610Count the Colors
    【例9.3】求最长不下降序列
    P1364 医院设置
    P1629 邮递员送信
    P1476 休息中的小呆
    P1330 封锁阳光大学
  • 原文地址:https://www.cnblogs.com/claremore/p/4721888.html
Copyright © 2011-2022 走看看