zoukankan      html  css  js  c++  java
  • 数据结构算法C语言实现(一)---2.2线性表的顺序表示和实现

      注意:

      虽然是用C语言实现,但是考虑到使用了一个C++的特性----引用以简化代码,所以所有的代码均以cpp作为后缀,用g++编译(以后不做说明)。

      g++版本:

      

      一.简述

      本节主要讲述线性表的顺序实现,主要操作包括建表插入元素删除元素查找元素合并表等操作,根据书中伪代码编写了C语言,使用int类型进行了测试,需要注意的是查找元素时使用了函数指针,C语言初学者不易理解,可查阅相关书籍学习。

      二.头文件

     1 //head.h
     2 /**
     3 My Code
     4 */
     5 #include <cstdio>
     6 #include <cstdlib>
     7 /**
     8 page 10
     9 */
    10 #define TRUE 1
    11 #define FALSE 0
    12 #define OK 1
    13 #define ERROR 0
    14 #define INFEASIBLE -1//不可行的
    15 #define OVERFLOW -2
    16 //Status是函数的类型,其值是函数结果状态代码
    17 typedef int Status;//注意分号不能少
    View Code

      三.CPP文件

    //2_2.cpp
    /**
    author:zhaoyu
    email:zhaoyu1995.com@gmail.com
    date:2016-6-4
    note:realize my textbook <<数据结构(C语言版)>>
    */
    
    #include "head.h"
    //----线性表的动态分配顺序存储结构----
    #define LIST_INIT_SIZE 100//线性表存储空间的初始分配量
    #define LISTINCREMENT 10//线性表存储空间的分配增量
    /**
    My Code
    to make the paragram run correctlly
    */
    #define ElemType int
    
    typedef struct {
        ElemType *elem;//存储空间基址
        int length;//当前长度
        int listsize;//当前分配的存容量(以sizeof(ElemType)位单位)
    }SqList;
    int compare(ElemType a, ElemType b)
    {
        return a==b?1:0;
    }
    /**
    algorithm 2.3
    page 23
    */
    Status InitList_Sq(SqList &L)
    {
        //构造一个空的线性表
        L.elem = (ElemType *)malloc(LIST_INIT_SIZE * sizeof(ElemType));
        if (!L.elem)
        {
            exit(OVERFLOW);
        }
        L.length = 0;
        L.listsize = LIST_INIT_SIZE;
        return OK;
    }//InitList_Sq
    
    /**
    algorithm 2.4
    */
    Status ListInsert_Sq(SqList &L, int i, ElemType e)
    {
        //在顺序线性表L中第i个位置之前插入新的元素e
        //i的合法为[1, ListLength_Sq(L)+1]
        if (i < 1 || i > L.length + 1)
        {
            return ERROR;//i值不合法
        }
        if (L.length >= L.listsize)
        {//当前存储空间已满,增加分配
            ElemType *newbase = (ElemType *)realloc(L.elem, (L.listsize + LISTINCREMENT)*sizeof(ElemType));
            if (!newbase)
            {
                exit(OVERFLOW);//存储分配失败
            }
            L.elem = newbase;//新基址
            L.listsize += LISTINCREMENT;//增加存储容量
        }
        ElemType *q = &(L.elem[i-1]);//q为插入位置
        for (ElemType *p = &L.elem[L.length-1]; p >= q; p--)
        {
            *(p+1) = *p;//插入位置及之后的元素右移
        }
        *q = e;
        ++L.length;
        return OK;
    }//ListInsert_Sq
    /**
    algorithm 2.5
    */
    Status ListDelete_Sq(SqList &L, int i, ElemType &e)
    {
        //在顺序线性表中删除第i个元素,并用e返回其值
        //i的合法值为[1, ListLength_Sq(L)]
        if ((i < 1) || (i > L.length))
        {
            return ERROR;//i为不合法值
        }
        ElemType *p = &(L.elem[i-1]);//p为被删除元素的位置
        e = *p;//被删除的元素赋值给e
        ElemType *q = L.elem + L.length - 1;//表位元素的位置
        for (++p; p <= q; ++p)
        {
            *(p-1) = *p;//被删除元素之后的元素左移
        }
        --L.length;//表长减 1
        return OK;
    }//ListDelete_Sq
    /**
    algorithm 2.6
    */
    int LocateElem_Sq(SqList L, ElemType e, Status(* compare)(ElemType, ElemType))
    {
        //在顺序线性表L中查找第1个值与e满足compare()的元素位序
        //若找到返回其在L中的位序,否则返回0
        int i = 1;//i的初值为第一个元素的位序
        ElemType *p = L.elem;//p为第一个元素的存储位置
        while (i <= L.length && !(*compare)(*p++, e))
        {
            ++i;
        }
        if (i <= L.length)
        {
            return i;
        }
        else
        {
            return 0;
        }
    }//LocateElem_Sq
    /**
    algorithm 2.7
    */
    void MergeList_Sq(SqList La, SqList Lb, SqList &Lc)
    {
        //已知顺序线性表La和Lb的元素按值非递减排列
        //归并La和Lb得到新的顺序线性表Lc,Lc的元素也按值非递减排列
        ElemType *pa = La.elem;
        ElemType *pb = Lb.elem;
        Lc.listsize = Lc.length = La.length + Lb.length;
        ElemType *pc = Lc.elem = (ElemType *)malloc(Lc.listsize*sizeof(ElemType));
        if (!Lc.elem)
        {
            exit(OVERFLOW);
        }
        ElemType *pa_last = La.elem + La.length - 1;
        ElemType *pb_last = Lb.elem + Lb.length - 1;
        while (pa <= pa_last && pb <= pb_last)
        {
            if (*pa <= *pb)
            {
                *pc++ = *pa++;
            }
            else
            {
                *pc++ = *pb++;
            }
        }
        while (pa <= pa_last)
        {
            *pc++ = *pa++;
        }
        while (pb <= pb_last)
        {
            *pc++ = *pb++;
        }
    }//MergeList_Sq
    /**
    My code
    */
    void PrintList(SqList L)
    {
        for (int i = 1; i <= L.length; i++)
        {
            printf("%d	", L.elem[i-1]);
        }
        printf("
    ");
    }
    /**
    My Test
    */
    int main(int argc, char const *argv[])
    {
        SqList La, Lb, Lc;
        InitList_Sq(La);
        InitList_Sq(Lb);
        InitList_Sq(Lc);
        //创建一个1 2 3 4的线性表
        ListInsert_Sq(La, 1, 10);
        ListInsert_Sq(La, 2, 20);
        ListInsert_Sq(La, 3, 30);
        ListInsert_Sq(La, 4, 50);
        PrintList(La);
        //在位序4(即值为5的位置)插 4
        ListInsert_Sq(La, 4, 40);
        PrintList(La);
        //创建线性表Lb;10, 20, 5, 30
        ListInsert_Sq(Lb, 1, 15);
        ListInsert_Sq(Lb, 2, 25);
        ListInsert_Sq(Lb, 3, 5);
        ListInsert_Sq(Lb, 4, 35);
        PrintList(Lb);
        int temp;
        //删除位置3的元素,并返回给 temp
        ListDelete_Sq(Lb, 3, temp);
        PrintList(Lb);
        printf("%d
    ", temp);
        //查找 30 在 Lb 的位置 
        printf("%d
    ", LocateElem_Sq(Lb, 30, compare));
        printf("%d
    ", LocateElem_Sq(Lb, 35, compare));
        //合并La, Lb 到 Lc,注意前提是有序的
        MergeList_Sq(La, Lb, Lc);
        PrintList(Lc);
        return 0;
    }
    View Code

      四.测试

         

  • 相关阅读:
    DIV高度设置全屏
    Yii2使用PHPExcel读取excel
    关于linux centos7 vmware 和windows7 文件共享笔记
    mysql rpm包安装
    linux crontab 计划任务脚本
    linux php5.6 安装
    linux上安装php phpredis扩展
    让微信小程序每次请求的时候不改变session_id的方法
    mysql主从配置
    mysql存储过程之游标遍历数据表
  • 原文地址:https://www.cnblogs.com/zhaoyu1995/p/5558473.html
Copyright © 2011-2022 走看看