顺序表原子操作的实现(C语言)

来源:互联网 发布:java zxing 二维码 编辑:程序博客网 时间:2024/05/16 14:03

以下三部分代码分别存为三个文件:
1. SqList.c文件

/*下面是用顺序存储实现的线性表:*///引入头文件#include <stdio.h>#include <stdlib.h>#include "SqList.h"//原子操作函数实现Status SqListInit(SqList * L)//初始化{    L->elem = (ElemType *)malloc(INIT_LIST_SIZE * sizeof(ElemType));    if (!L->elem)    {        exit(OVERFLOW);//如果分配失败,退出程序    }    L->length = 0;    L->listSize = INIT_LIST_SIZE;    return OK;}void SqListDestroy(SqList * L)//销毁{    free(L->elem);    L->elem = NULL;    L->length = 0;    L->listSize = 0;}void SqListClear(SqList * L)//清空{    L->length = 0;}Status SqListEmpty(SqList * L)//检查是否为空{    if(0 == L->length)    {        return true;    }    else    {        return false;    }}Status SqListPriorElem(SqList * L, ElemType * curElem, ElemType * priorElem)//找指定元素的前一个元素{    //表不是空的    if ( !SqListEmpty(L) )    {        //这个元素是表中的元素,并且不是第一个元素        int i = 0;        int length = L->length;        for (i = 1; i < length; ++i)//由于不能是第一个元素,所以第一个元素不参与比较        {            if ( *curElem == *(L->elem + i) )            {                * priorElem =  *(L->elem + i - 1);                return OK;            }        }    }    return ERROR;}Status SqListNextElem(SqList * L, ElemType * curElem, ElemType * nextElem)//找指定元素的后一个元素{    //表不是空的    if ( !SqListEmpty(L) )    {        //这个元素是表中的元素,并且不是最后一个元素        int i = 0;        int length = L->length;        for (i = 0; i < length - 1; ++i)//由于不能是最后一个元素,所以最后一个元素不参与比较        {            if ( *curElem == *(L->elem + i) )            {                * nextElem =  *(L->elem + i + 1);                return OK;            }        }    }    return ERROR;}unsigned int SqListLength(SqList * L)//求出一个顺序表的表长{    return L->length;}Status SqListGetElem(SqList * L, unsigned int location, ElemType * elem)//获取指定位置的一个元素{    int index = location - 1;    //先要判断位置是否合法    if ( (location < 1) || (location > L->length))    {        return ERROR;    }    else    {        //然后找到对应位置的元素并将其返回,假设要找第一个,那么就是 L.elem + 0        *elem = *(L->elem + index);        return OK;    }}unsigned int SqListLocationElem(SqList * L, ElemType * elem)//定位指定元素的位置{    unsigned int length = L->length;    unsigned int index = 0;    for (index = 0; index < length; ++index)    {        if ( *(L->elem + index) == *elem)        {            return index + 1;        }    }    return false;}Status SqListInsert(SqList * L, unsigned int location, ElemType * elem)//向表中插入一个元素{    unsigned int length = L->length;    unsigned int old_size = L->listSize;    int i = 0;    //首先判断位置是否合法    if ((location < 1) || (location > length + 1))    {        return ERROR;    }    else    {        //然后判断是否需要扩充顺序表        if (length >= old_size)        {            //下面进行扩容            L->elem = (ElemType *)realloc(L->elem , (old_size + LIST_INCREMENT) * sizeof(ElemType));            L->listSize = old_size + LIST_INCREMENT;        }        //向表中插入元素        //首先将插入位置以后的元素全部向后移动一位,从表尾元素开始移动        for (i = length; i >= location; --i)        {            *(L->elem + i) = *(L->elem + i - 1);        }        //之后将要插入的元素插入        *(L->elem + location - 1) = *elem;        //最后表长加一        ++(L->length);        return OK;    }}Status SqListAppend(SqList * L, ElemType * elem)//向表中追加一个元素{    //首先判断是否需要扩充顺序表    unsigned int length = L->length;    unsigned int old_size = L->listSize;    if (length >= old_size)    {        //下面进行扩容        L->elem = (ElemType *)realloc(L->elem , (old_size + LIST_INCREMENT) * sizeof(ElemType));        L->listSize = old_size + LIST_INCREMENT;    }    //之后将要插入的元素插入表尾    *(L->elem + length) = * elem;    //最后表长加一    ++(L->length);    return OK;}Status SqListElemDelete(SqList * L, unsigned int location, ElemType * elem)//删除指定位置的元素值,并且将删除的元素值带回{    unsigned int length = L->length;    int i = 0;    //首先判断指定的位置是否合法    if ((location <= 0) || location > length)    {        return ERROR;//位置不合法    }    else    {        //之后找到指定位置的元素,用elem带回        *elem = *(L->elem + location - 1);        //然后删除指定位置的元素值        //将指定位置之后的元素依次向前移动一个位置,从指定位置之后的一个元素开始移动        for (i = location; i < length; ++i)        {            *(L->elem + i - 1) = *(L->elem + i);        }        //最后表长减一        --L->length;        return OK;    }}void SqListTraverse(SqList * L, void (*function)(ElemType))//遍历整个顺序表,并且对顺序表中的每一个元素执行指定操作{    int i = 0;    int length = L->length;    for (i = 0; i < length; ++i)    {        function( *(L->elem + i) );    }}void SqListPrint(SqList * L)//打印一个顺序表{    int i = 0;    for (i = 0; i < L->length; ++i)    {        printf("%d ", *(L->elem + i));    }}void SqListSortSTB(SqList *L)//将数据由小到大排序{    //冒泡排序    int i = 0, j = 0, temp = 0;    int length = L->length;    for (i = 0; i < length; ++i)    {        for (j = i; j < length; ++j)        {            if ( *( L->elem + i ) > *( L->elem + j ) )            {                temp = *( L->elem + i );                *( L->elem + i ) = *( L->elem + j );                *( L->elem + j ) = temp;            }        }    }}void SqListUnion(SqList *La, SqList *Lb, SqList *Lc)//取La和Lb的并集,然后将产生的并集用Lc带回{    int i = 0, j = 0;//循环计数    unsigned int LaSize = La->listSize, LbSize = Lb->listSize;    //先创建表Lc,表的容量是:La和Lb两个表的和    Lc->elem = malloc ( (LaSize + LbSize) * sizeof(ElemType));    Lc->listSize = LaSize + LbSize;    Lc->length = 0;//表Lc现在是空的    //将La这个表复制一遍到Lc    for (i = 0; i < La->length; ++i)    {        *(Lc->elem + i) = *(La->elem + i);    }    Lc->length = La->length;    //然后每次拿出Lb中的一个元素和Lc中的每一个元素比较,如果没有相同的,那么就将这个元素追加到Lc中,否则不添加    for (i = 0; i < Lb->length; ++i)    {        for (j = 0; j < Lc->length; ++j)        {            if ( *(Lb->elem + i) == *(Lc->elem + j))            {                //当在表Lc里面找到了和Lb一样的元素,那么这个元素就不加入Lc了                break;//退出,换Lb里面的下一个元素            }        }        //出内层循环的时候,就表明在Lc中没有这个元素,应该将这个元素添加到Lc中        if (j == Lc->length)        {            //将此时的Lb中的元素添加到Lc中            *(Lc->elem + j) = *(Lb->elem + i);            ++(Lc->length);        }    }}void SqListIntersection(SqList *La, SqList *Lb, SqList *Lc)//取La和Lb的交集,然后将产生的并集用Lc带回{    int i = 0, j = 0;//循环计数    unsigned int LaSize = La->listSize, LbSize = Lb->listSize, LcSize = 0;    //先创建表Lc,表的容量是:La和Lb两个表的表长的较小值    if (LaSize > LbSize)    {        LcSize = LbSize;    }    else    {        LcSize = LaSize;    }    Lc->elem = malloc ( (LcSize) * sizeof(ElemType));    Lc->listSize = LcSize;    Lc->length = 0;//表Lc现在是空的    //然后每次拿出La中的一个元素和Lb中的每一个元素比较,如果有相同的,那么就将这个元素追加到Lc中,否则不添加    for (i = 0; i < La->length; ++i)    {        for (j = 0; j < Lb->length; ++j)        {            if ( *(La->elem + i) == *(Lb->elem + j))            {                //当在表Lb里面找到了和La一样的元素,那么表La中的这个元素加入Lc                *(Lc->elem + Lc->length) = *(La->elem + i);                ++(Lc->length);//表长加一            }        }    }}void SqListDifferentSets(SqList *La, SqList *Lb, SqList *Lc)//取La和Lb的差集,(Lc=La-Lb)然后将产生的差集用Lc带回{    int i = 0, j = 0;//循环计数    unsigned int LaSize = La->listSize;    //先创建表Lc,表的容量是:La的容量    Lc->elem = malloc ( (LaSize) * sizeof(ElemType));    Lc->listSize = LaSize;    Lc->length = 0;//表Lc现在是空的    //然后每次拿出La中的一个元素和Lb中的每一个元素比较,如果有相同的,那么就不将这个元素追加到Lc中,否则添加到Lc中    for (i = 0; i < La->length; ++i)    {        for (j = 0; j < Lb->length; ++j)        {            if ( *(La->elem + i) == *(Lb->elem + j))            {                break;//只要找到了相同的,就不往Lc中插入            }        }        if (j == Lb->length)//出内层循环就说明没有找到相同的元素        {            //当在表Lb里面没有找到和La一样的元素,那么La中的这个元素加入Lc            *(Lc->elem + Lc->length) = *(La->elem + i);            ++(Lc->length);//表长加一        }    }}

2.SqList.h文件

//状态字声明#ifndef STATUS_WORD#define STATUS_WORD#define OK 1#define ERROR 0#define true 1#define false 0#define OVERFLOW -1#endif#ifndef SqLIST_H#define SqLIST_H#define INIT_LIST_SIZE 100#define LIST_INCREMENT 10typedef int Status;typedef int ElemType;//假设元素类型都是int类型//顺序表结构定义typedef struct SqList{    ElemType * elem;    unsigned int length;    unsigned int listSize;} SqList;//顺序表库函数声明Status SqListInit(SqList * L);//初始化void SqListDestroy(SqList * L);//销毁void SqListClear(SqList * L);//清空Status SqListEmpty(SqList * L);//检查是否为空Status SqListPriorElem(SqList * L, ElemType * curElem, ElemType * priorElem);//找指定元素的前一个元素Status SqListNextElem(SqList * L, ElemType * curElem, ElemType * nextElem);//找指定元素的后一个元素unsigned int SqListLength(SqList * L);//求表长Status SqListGetElem(SqList * L, unsigned int location, ElemType * elem);//获取指定位置的元素unsigned int SqListLocationElem(SqList * L, ElemType * elem);//定位指定元素的位置Status SqListInsert(SqList * L, unsigned int location, ElemType * elem);//插入元素Status SqListAppend(SqList * L, ElemType * elem);//追加元素Status SqListElemDelete(SqList * L, unsigned int location, ElemType * elem);//删除指定位置的元素,并且将删除的元素带回void SqListTraverse(SqList * L, void (*function)(ElemType));//遍历整个顺序表,并且对顺序表中的每一个元素执行指定操作void SqListPrint(SqList *L);//打印void SqListSortSTB(SqList *L);//将数据由小到大排序void SqListUnion(SqList *La, SqList *Lb, SqList *Lc);//取La和Lb的并集,然后将产生的并集用Lc带回void SqListIntersection(SqList *La, SqList *Lb, SqList *Lc);//取La和Lb的交集,然后将产生的交集用Lc带回void SqListDifferentSets(SqList *La, SqList *Lb, SqList *Lc);//取La和Lb的差集,(Lc=La-Lb)然后将产生的差集用Lc带回//void SqListResearch(SqList *L);//查找#endif

3.main.c文件//这个文件里面是主函数,只用来测试

#include "SqList.h"#include <stdio.h>//测试相关声明void visit(ElemType);void test1(SqList * La);//typedef的用法:将一个数据类型起一个别名//这里,typedef将"指向返回值是void,参数是ElemType类型的函数的指针"这个类型起了一个别名,叫做:FunType//注意:第二个括号后面不再写东西//比如:typedef int * PINT 就是将"指向int类型的指针"这个类型起一个叫做PINT的别名//typedef void (*FunType)(ElemType);int main(void){    SqList La;//创建一个顺序表    SqList Lb;    SqList Lc;    ElemType e1;//创建一个元素    ElemType e2;//创建一个元素    unsigned int location = 0;//创建一个位置    SqListInit(&La);//初始化一个顺序表    SqListInit(&Lb);    printf("初始化一个顺序表后:");    test1(&La);    e1 = 100;    printf("向表中追加一个元素100:\n");    SqListAppend(&La, &e1);//向表中追加一个元素    test1(&La);    e1 = 569;    printf("向表中追加一个元素569:\n");    SqListAppend(&La, &e1);//向表中追加一个元素    test1(&La);    e1 = 100;    printf("向表中追加一个元素100:\n");    SqListAppend(&Lb, &e1);//向表中追加一个元素    test1(&Lb);    e1 = 314;    printf("向表中追加一个元素314:\n");    SqListAppend(&Lb, &e1);//向表中追加一个元素    test1(&Lb);    printf("将表Lb和表La合并之后的集合是:\n");    SqListUnion(&La, &Lb, &Lc);//取La和Lb的并集,然后将产生的并集用Lc带回    test1(&Lc);    printf("将表Lb和表La取交集之后的集合是:\n");    SqListIntersection(&La, &Lb, &Lc);//取La和Lb的交集,然后将产生的交集用Lc带回    test1(&Lc);    printf("将表Lb和表La取差集之后的集合是:\n");    SqListDifferentSets(&La, &Lb, &Lc);//取La和Lb的差集,然后将产生的差集用Lc带回    test1(&Lc);    e1 = 99;    printf("向表中再追加一个元素99:\n");    SqListAppend(&La, &e1);//向表中追加一个元素    test1(&La);    e1 = 200;    SqListInsert(&La, 1, &e1);//向表中插入一个元素    printf("向表中的第一个位置插入元素200:\n");    test1(&La);    e1 = 44;    SqListInsert(&La, La.length + 1, &e1);//向表尾插入一个元素    printf("向表中的最后一个位置插入元素44:\n");    test1(&La);    SqListGetElem(&La, 1, &e1);//获取某一个元素    printf("第一个元素的值是:%d\n", e1);    SqListSortSTB(&La);    printf("测试遍历函数:打印整个顺序表:\n");    SqListTraverse(&La, visit);//函数指针作为参数时,只写函数的名字即可    e1 = 44;    if (SqListPriorElem(&La, &e1, &e2))    {        printf("%d的前面一个元素是:%d\n", e1, e2);    }    e1 = 88;    if (SqListNextElem(&La, &e1, &e2))    {        printf("%d的后面一个元素是:%d\n", e1, e2);    }    location = SqListLocationElem(&La, &e1);    if (location > 0)//定位某个元素的位置    {        printf("%d这个元素的位置是:%d\n", e1, location);    }    printf("删除第八个元素\n");    if(SqListElemDelete(&La, 8, &e1))//删除第八个元素    {        printf("第八个元素是:%d\n", e1);    }    else    {        printf("删除失败!\n");    }    test1(&La);    printf("删除第二个元素\n");    if(SqListElemDelete(&La, 2, &e1))//删除第八个元素    {        printf("第二个元素是:%d\n", e1);    }    else    {        printf("删除失败!\n");    }    test1(&La);    printf("测试遍历函数:打印整个顺序表:\n");    SqListTraverse(&La, visit);//函数指针作为参数时,只写函数的名字即可    SqListClear(&La);//清空一个顺序表    printf("清空这个顺序表之后:");    test1(&La);    SqListDestroy(&La);//销毁一个顺序表    return 0;}//测试函数实现void visit(ElemType elem)//打印一个元素{    printf("%d\n", elem);}void test1(SqList * La)//判断表示否空并且打印出所有元素{    if (SqListEmpty(La))//检查一个顺序表是否为空    {        printf("表现在是空的。\n");    }    else    {        printf("表现在不是空的。\n");        printf("顺序表现在的长度是:%d\n", SqListLength(La));//求出一个顺序表的表长        printf("现在表中的元素有:\n");        SqListPrint(La);//打印一个顺序表    }}
0 0
原创粉丝点击