再写顺序表(c语言实现,外加冒泡排序,二分查找)

概念

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组 上完成数据的增删查改。

  • 顺序表一般可以分为:
  1. 静态顺序表:使用定长数组存储。
  2. 动态顺序表:使用动态开辟的数组存储。
头文件声明

SeqList.h

#pragma once
#include<stdbool.h>typedef int SDataType;
/*
//静态顺序表
typedef struct SeqList{SDataType array[100]; //能存100个数的静态顺序表int size;      //表是当前顺序表中有多少个数,顺便也表示了即将插入的下标} SeqList;
*///动态顺序表
typedef struct SeqList{SDataType *array;		//指上堆上的空间int size;      //表是当前顺序表中有多少个数,顺便也表示了即将插入的下标int capacity;	//容量
} SeqList;//初始化/销毁
//seqlist 是一个变量的地址
//capacity 表示顺序表的容量
void SeqListInit(SeqList * seqlist,int capacity);
void SeqListDestroy(SeqList * seqlist);//增删改查//插入 (前,中,后)
//尾插
void SeqListPushBack(SeqList *seqlist, SDataType value);
//头插
void SeqListPushFront(SeqList * seqlist, SDataType value);
//中间插入
void SeqListInsert(SeqList *seqlsit, int pos, SDataType value);//删除
//尾删
void SeqListPopBack(SeqList *seqlist);
//头删
void SeqListPopFront(SeqList *seqlist);
//删除pos所在的下标的数据
void SeqListErase(SeqList *seqlist, int pos);//打印
void SeqListPrint(const SeqList *seqlist);
//修改pos所在下标的数据为value
void SeqListModify(SeqList *seqlist, int pos, SDataType value);
//查找
int SeqListFind(const SeqList *seqlist, SDataType value);
//找到并删除遇到的第一个value
void SeqListRemove(SeqList *seqlist, SDataType value);
//判断顺序表是否为空
bool SeqListEmpty(const SeqList *seqlist);
//返回数据个数
int SeqListSize(const SeqList *seqlist);//冒泡排序
void SeqListBubbleSort(SeqList *seqlist);
//二分查找
int SeqListSort(const SeqList *seqlist, SDataType value);
//删除遇到的所有value
void SeqListRemoveAll(SeqList *seqlist, SDataType value);
顺序表主要功能实现

SeqList.c

#include"SeqList.h"
#include<assert.h>
#include<malloc.h>
#include<stdio.h>
#include<stdlib.h>//检查是否需要扩容,如果需要扩容就进行扩容
//保证函数结束后,容量一定够用
static void CheckCapacity(SeqList *seqlist)
{assert(seqlist != NULL);assert(seqlist->array != NULL);assert(seqlist->size <= seqlist->capacity);if (seqlist->size < seqlist->capacity){return;}//空间扩大两倍int capacity = 2 * seqlist->capacity;//申请新空间SDataType *array = (SDataType *)malloc(sizeof(SDataType)*capacity);assert(array);//搬移for (int i = 0; i < seqlist->size; i++){array[i] = seqlist->array[i];}//释放原空间free(seqlist->array);seqlist->array = array;
}void SeqListInit(SeqList * seqlist, int capacity)
{assert(seqlist != NULL);seqlist->array = (SDataType*)malloc(sizeof(SDataType)* capacity);assert(seqlist->array);seqlist->size = 0;seqlist->capacity = capacity;
}void SeqListDestroy(SeqList * seqlist)
{assert(seqlist != NULL);assert(seqlist->array != NULL);free(seqlist->array);seqlist->array = NULL;seqlist->size = 0;seqlist->capacity = 0;
}
//尾插
void SeqListPushBack(SeqList *seqlist, SDataType value)
{assert(seqlist != NULL);assert(seqlist->array !=NULL);CheckCapacity(seqlist);seqlist->array[seqlist->size] = value;seqlist->size++;
}
//尾删
void SeqListPopBack(SeqList *seqlist)
{assert(seqlist != NULL);assert(seqlist->array != NULL);assert(seqlist->size > 0); //数据元素个数大于0seqlist->size--;
}
//头插
/*1. 从后往前搬,避免覆盖2. 写循环先确定循环的边界i 空间下表 [size,0)i 数据下标 [size -1,0]3. 搬移空间下标:array[i] = array[i-1];数据下标:array[i+1] = array[i];
*/
void SeqListPushFront(SeqList * seqlist, SDataType value)
{assert(seqlist != NULL);assert(seqlist->array != NULL);CheckCapacity(seqlist);//做数据的搬移,i代表空间下标for (int i = seqlist->size; i > 0; i--){seqlist->array[i] = seqlist->array[i - 1];}seqlist->array[0] = value;seqlist->size++;
}
//前删
void SeqListPopFront(SeqList *seqlist){assert(seqlist != NULL);assert(seqlist->array != NULL);assert(seqlist->size > 0);#if 0for (int i = 0; i < seqlist->size; i++){seqlist->array[i] = seqlist->array[i + 1];}
#endiffor (int i = 1; i < seqlist->size; i++){seqlist->array[i - 1] = seqlist->array[i];}seqlist->size--;
}//中间插
void SeqListInsert(SeqList *seqlist, int pos, SDataType value){assert(seqlist != NULL);assert(seqlist->array != NULL);assert(pos >= 0 && pos <= seqlist->size);CheckCapacity(seqlist);for (int i = seqlist->size - 1; i >= pos; i--){seqlist->array[i + 1] = seqlist->array[i];}seqlist->array[pos] = value;
}//中间删
void SeqListErase(SeqList *seqlist, int pos){assert(seqlist!= NULL);assert(seqlist->array != NULL);assert(seqlist->size > 0);assert(pos >= 0 && pos < seqlist->size);
#if 0//i代表数据for (int i = pos; i < seqlist->size - 1; i++){seqlist->array[i] = seqlist->array[i + 1];}
#endif//i代表数据for (int i = pos + 1; i < seqlist->size ; i++){seqlist->array[i - 1] = seqlist->array[i];}seqlist->size--;
}//打印
void SeqListPrint(const SeqList *seqlist){for (int i = 0; i < seqlist->size; i++)printf("%d", seqlist->array[i]);printf("\n");
}
//修改pos所在下标的数据为value
void SeqListModify(SeqList *seqlist, int pos, SDataType value){assert(pos >= 0 && pos < seqlist->size);seqlist->array[pos] = value;
}
//查找
//找到返回下标
//没找到返回-1
int SeqListFind(const SeqList *seqlist, SDataType value){for (int i = 0; i < seqlist->size; i++){if (seqlist->array[i] == value){return i;}}return -1;
}
//找到并删除遇到的第一个value
void SeqListRemove(SeqList *seqlist, SDataType value){int pos = SeqListFind(seqlist, value);if (pos != -1){SeqListErase(seqlist, pos);}
}
//判断顺序表是否为空
bool SeqListEmpty(const SeqList *seqlist){return seqlist->size == 0;
}
//返回数据个数
int SeqListSize(const SeqList *seqlist){return seqlist->size;
}void Swap(int *a, int *b)
{int t = *a;*a = *b;*b = t;
}//冒泡排序
void BubbleSort(int array[], int size)
{int isSorted; //如果数组本身有序,就可以优化for (int i = 0; i < size - 1; i++){isSorted = 1; //1代表有序//一次冒泡过程//一次冒泡过程中,如果没有交换就说明本身有序for (int j = 0; j < size - 1 - i; j++){if (array[j]>array[j + 1]){Swap(array + j, array + j + 1);//Swap(&array[i])isSorted = 0;}}//一次冒泡结束if (isSorted == 1){break;}}
}//冒泡排序
void SeqListBubbleSort(SeqList *seqlist){BubbleSort(seqlist->array, seqlist->size);
}//二分查找
int SeqListSort(const SeqList *seqlist, SDataType value)
{int left = 0;int right = seqlist->size;while (left < right){int mid = (right - left) / 2 + left;if (value == seqlist->array[mid]){return mid;}else if (value < seqlist->array[mid]){right = mid;}else{left = mid + 1;}}return -1;
}void SeqListRemoveAll(SeqList *seqlist, SDataType value){
#if 0 //O(N*2) O(1)int pos;while ((pos = SeqListFind(seqlist, value)) != -1){SeqListErase(seqlist, pos);}
#endif#if 0 //O(N) O(N)//开辟新数组SDataType *array = (SDataType *)malloc(sizeof(SDataType)* seqlist->size);assert(array);//搬出去int index = 0;for (int i = 0; i < seqlist->size; i++){if (seqlist->array[i] != value){array[index] = seqlist->array[i];index++;}}//搬回去for (int j = 0; j < index; j++){seqlist->array[j] = array[j];}seqlist->size = index;
#endifint index = 0;for (int i = 0; i < seqlist->size; i++){if (seqlist->array[i] != value){seqlist->array[index] = seqlist->array[i];index++;}}seqlist->size = index;
}
测试用例

Main.c

#include"SeqList.h"void TestSeqList1()
{SeqList seqlist;SeqListInit(&seqlist, 100);SeqListPushBack(&seqlist, 1);SeqListPushBack(&seqlist, 2);SeqListPushBack(&seqlist, 3);//1,2,3SeqListPushFront(&seqlist, 11);SeqListPushFront(&seqlist, 12);SeqListPushFront(&seqlist, 13);//13,12,11,1,100,2,3SeqListInsert(&seqlist, 4, 100);//13,12,11,1,100,2,3SeqListPopBack(&seqlist);//13,12,11,1,100,2SeqListPopFront(&seqlist);//12,11,1,100,2SeqListErase(&seqlist, 3);//12,11,100,2SeqListDestroy(&seqlist);
}void TestSeqList2()
{SeqList seqlist;SeqListInit(&seqlist, 10);SeqListPushBack(&seqlist, 3);SeqListPushBack(&seqlist, 5);SeqListPushBack(&seqlist, 2);SeqListPushBack(&seqlist, 7);SeqListPushBack(&seqlist, 9);SeqListPushBack(&seqlist, 4);SeqListPushBack(&seqlist, 8);SeqListPushBack(&seqlist, 6);SeqListPushBack(&seqlist, 1);SeqListPushBack(&seqlist, 0);SeqListBubbleSort(&seqlist);int r = SeqListSort(&seqlist, 3);printf("%d\n", r);SeqListPrint(&seqlist);
}int main()
{TestSeqList2();system("pause");return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/383180.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

再写单链表(不带头单链表)

单链表 实际中链表的结构非常多样&#xff0c;以下情况组合起来就有8种链表结构&#xff1a; 单向、双向带头、不带头循环、非循环 虽然有这么多的链表的结构&#xff0c;但是我们实际中最常用还是两种结构&#xff1a; 无头单向非循环链表&#xff1a;结构简单&#xff0…

再写双向循环链表

#pragma once #include<assert.h> #include<malloc.h> #include<stdio.h> typedef int DLDataType;//定义链表结点结构 typedef struct DListNode{DLDataType value;struct DListNode *prev; //指向前一个结点struct DListNode *next; //指向后一个结点 } DL…

链表题目--1 删除链表中所有等于val的值

注意事项 要删除的结点相邻第一个结点就是要删除的结点 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* removeElements(struct ListNode* head, int val){if(headNULL){return NULL;}struct …

链表题目--2 求链表的中间结点 和 求链表中倒数第k个结点

求链表的中间结点 思路 一个走两步&#xff0c;一个走一步。一个走到尾&#xff0c;另外一个就走到了中间 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* middleNode(struct ListNode* head…

链表题目---3 合并两个有序单链表 和 分割链表

合并两个有序单链表 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){if(l1 NULL){return l2;}else if(l2 NULL){return l1;}struc…

链表题目---4 删除链表中重复的结点 和 判断链表是否为回文链表

删除链表中重复的结点 /* struct ListNode {int val;struct ListNode *next;ListNode(int x) :val(x), next(NULL) {} }; */ class Solution { public:ListNode* deleteDuplication(ListNode* pHead){if(pHead NULL){return NULL;}ListNode *prev NULL; //用于删除的结点, 是…

链表题目----5 相交链表 和 环形链表 和 返回链表开始入环的第一个节点

相交链表 思路 链表交叉不可能是x型因为有可能两个链表不等长&#xff0c;所以我们必须让他们从同一起跑位置去起跑从同一起跑位置出发&#xff0c;依次比较每个结点的地址是否相同 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct L…

链表题目---6 复制带随机指针的链表

思路 将新结点放在老结点的后面 复制random 将链表拆开 /* // Definition for a Node. class Node { public:int val;Node* next;Node* random;Node() {}Node(int _val, Node* _next, Node* _random) {val _val;next _next;random _random;} }; */ class Solution { publi…

括号匹配问题(c和c++版本实现)

括号匹配问题 思路 遇见左括号入栈&#xff0c;遇见一个右括号弹出栈顶元素右括号入栈前如果栈已经为空&#xff0c;则不匹配如果不为空则读取并弹出&#xff0c;弹出来的元素与右括号做比较&#xff0c;必须匹配&#xff0c;不匹配返回false;如果最后栈里还有元素&#xff0c…

用队列实现栈 AND 用栈实现队列

用队列实现栈 思路 入队列就是入栈出队列的时候&#xff0c;就是把前面size-1个队列中的元素先出&#xff0c;这样最后一个元素就成队首元素了&#xff0c;再把出去的元素再次入队列读栈顶元素&#xff0c;过程和第二步是一样的&#xff0c;就是弹出后&#xff0c;再把它入队列…

最小栈的实现(设计一个支持 push,pop,top 操作,并能在常数时间内检索到最小元素的栈。)

最小栈的实现 思路 两个栈&#xff0c;左边栈接受元素&#xff0c;右边栈存最小的元素入栈时&#xff0c;先入左边栈&#xff0c;随后进行比较&#xff0c;左边和右边栈顶元素进行比较&#xff0c;如果新元素小&#xff0c;就把新元素放在右边的栈顶位置&#xff0c;如果新元素…

再写循环队列----c++实现

再写循环队列 class MyCircularQueue { public:/** Initialize your data structure here. Set the size of the queue to be k. */MyCircularQueue(int k) {array (int *)malloc(sizeof(int)*k);capacity k;size 0;front 0;rear 0;}/** Insert an element into the circu…

再谈二叉树(二叉树概念,二叉树的性质,二叉树的存储结构)

树的概念 树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因 为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。它具有以下的特点&#xff1a;每个…

二叉树题目----1 前序中序后序遍历二叉树并返回相应的遍历(不是打印)

前序遍历 /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* struct TreeNode *right;* };*//*** Note: The returned array must be malloced, assume caller calls free().*/ int *array; int size;void _preorde…

二叉树题目----2 检查两颗树是否相同 和 对称二叉树的判定

检查两颗树是否相同 思路 根要相等 p->val q->val左子树相等 isSameTree(p->left,q->left)右子树也要相等 isSameTree(p->right,q->right) /*** Definition for a binary tree node.* struct TreeNode {* int val;* struct TreeNode *left;* …

二叉树题目---3 另一个树的子树 AND 二叉树最大深度

另一个树的子树 思路 两个数都遍历一遍&#xff0c;找到一个根结点相同时&#xff0c;判断以这个根结点为首的二叉树是否相等 前序遍历判断两棵树是否相同对于返回值的处理是难点 bool isSameTree(struct TreeNode *p, struct TreeNode *q) {if(p NULL && q NULL)…

二叉树题目----4 前序遍历重构二叉树 AND 求二叉树中所有结点的个数

前序遍历重构二叉树 思路 整个二叉树用数组存储因为先序遍历它先遍历根&#xff0c;再遍历左&#xff0c;左边没有跑完是不会去遍历右边的&#xff0c;所以遍历左子树&#xff0c;就是数组元素每回向后一个&#xff0c;个数-1遍历右边时&#xff0c;就是数组起始位置左子树跑到…

二叉树的进阶操作---(求二叉树中所有结点个数,求叶子结点个数,求第k层结点个数;在二叉树中查找某一结点;层序遍历;判断是否为完全二叉树)

typedef struct TreeNode {struct TreeNode *left;struct TreeNode *right;char val; }TreeNode;typedef struct Result{TreeNode * root; //构建的树的根结点int used; //构建过程中用掉的val个数 } Result;求二叉树中所有结点个数 void TreeSize(TreeNode *root, int …

c++中的智能指针详解(RAII, auto_ptr的原理及其改进,unique_ptr的原理,shared_ptr的原理,shared_ptr的缺陷及其改进)

为什么需要智能指针 代码中途退出&#xff0c;也能保证资源的合理释放&#xff0c;在c中没有垃圾回收机制的情况下&#xff0c;智能指针就可以保证我们申请的资源&#xff0c;最后忘记释放的问题&#xff0c;防止内存泄露&#xff0c;也帮我们减少了一定的负担&#xff0c;不用…

Job for mariadb.service failed because the control process exited with error code. Se

错误&#xff1a;[rootlocalhost ~]# systemctl start mariadb.service Job for mariadb.service failed because the control process exited with error code. See “systemctl status mariadb.service” and “journalctl -xe” for details. 解决办法&#xff1a; [rootl…