顺序表原子操作的实现(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
- 顺序表原子操作的实现(C语言)
- C语言顺序表的插入、删除、查找操作实现
- C语言实现顺序表的所有操作代码
- c语言顺序表的实现与基本操作
- C语言实现顺序表的基本操作
- 静态与动态顺序表操作的C语言实现
- C语言:静态顺序表的实现和相关操作
- C语言实现----顺序表的基本操作(1)
- 顺序线性表的基本操作(C语言实现)
- C语言 简单的 顺序表操作
- C语言顺序表的基本操作
- 单链表顺序存储相关操作的c语言实现
- C语言实现顺序栈的基本操作
- C语言实现顺序栈的基本操作
- Atom原子C语言实现
- 线性表的顺序实现(C语言)
- 顺序表的C语言实现
- 线性表的顺序实现(c语言)
- POJ2313 Sequence
- MySQL 安装和启动服务,“本地计算机 上的 MySQL 服务启动后停止。某些服务在未由其他服务或程序使用时将自动停止。”
- 练习
- acm 斐波那契博弈(裸题代码)
- 100个直接可以拿来用的JavaScript实用功能代码片段
- 顺序表原子操作的实现(C语言)
- AI不可怕,就怕AI会画画——这里有一种你还不知道的‘图’灵测试…
- LeetCode117 Populating Next Right Pointers in Each Node II
- 技术男留存的好网站,再此收藏!
- 源码阅读--OkHttp3
- 火焰图相关的一些东西
- CodeForces 798A Mike and palindrome
- #HDU3435#A new Graph Game(环+KM)
- Ubuntu输入su提示认证失败的解决方法