数据结构 顺序表(C语言 与 Java实现)以及部分练习题
数据结构
数组(顺序表)
- 一组相同数据类型的集合
特点
- 数组在内存中是连续分配的 如上图
- 创建时要指明数组的大小
数组名
代表首地址,索引从0
开始,到数组的长度-1
- 数组一旦创建好,大小不可以改变
- 使用索引
- 获取索引位置的值
arr[index]
- 修改
arr[index] = val
- 删除 (假删除)
就是把目标元素后面的元素向前位移一格
- 遍历,将数组中的元素,依次打印出来
- 获取索引位置的值
使用Java实现更高级的数组
import java.util.Random;
public class MyArr<T> {
private int capacity = 0;
private int size = 0;
private T[] arr;
public MyArr(int capacity) {
if (capacity < 0) this.capacity = 10; //if no right input, we will initial capacity 10
this.capacity = capacity;
this.arr = (T[]) new Object[capacity];
}
public int getCapacity() {
return capacity;
}
public int getSize() {
return size;
}
public T[] setCapacity(int capacity) {
if (capacity < 0) {
throw new RuntimeException("扩大小异常");
}
this.capacity = capacity;
T[] newNum = (T[]) new Object[capacity];
for (int i = 0; i < this.size; ++i) {
newNum[i] = this.arr[i];
}
return newNum;
}
//增加元素
public void add(T val) {
if (this.size >= this.capacity) {
this.arr = setCapacity(2 * this.capacity);
}
this.arr[this.size++] = val;
}
//删除元素
public boolean removeByIndex(int index) {
if (index < 0 || index > this.capacity) {
throw new RuntimeException("数组越界");
}
for (int i = index; i < size - 1; ++i) {
arr[i] = arr[i + 1];
}
size--;
if (size < this.capacity / 4 && this.capacity > 4) {
arr = setCapacity(this.capacity / 4);
}
return true;
}
//修改位置元素
public void modify(int index, T val) {
if (index < 0 || index > size - 1) {
throw new RuntimeException("数组越界");
}
arr[index] = val;
}
//获取某元素位置
public int locateVal(T val) {
for (int i = 0; i < size; ++i) {
if (arr[i] == val) {
return i;//return index
}
}
// if no find return -1
return -1;
}
//打印元素
@Override
public String toString() {
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append('[');
for (int i = 0; i < this.size - 1; ++i) {
stringBuffer.append(arr[i] + ",");
}
if(size>0) stringBuffer.append(arr[size - 1]);
stringBuffer.append(']');
return stringBuffer.toString();
}
}
C语言实现
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include <stdlib.h> // 添加头文件以使用malloc和free函数
#define ERROR 0
#define OK 1
#define MAXLENGTH 20
#define List_Increment 10
typedef int Status;//判断程序是否运行成功 0-失败 1-成功
typedef int Element;
typedef struct {
Element* location;
int length;//存储数据结构数组长度
int listsize;//
}SqList;
//初始化顺序表
Status initiElem(SqList *L) {
//L->location = Element stu[20];
L->location = (Element*)malloc(MAXLENGTH*sizeof(Element));
L->length = 0 ;
L->listsize = 0;
if (L->location == NULL) {
return ERROR ;//申请内存失败
}
return OK;//申请内存成功
}
//插入元素
Status insertElem(SqList* L, int i, Element e) {
if (L->length == MAXLENGTH) return ERROR;//表饱和
if (i<1 || i>L->length + 1) return ERROR;
if (i <= L->length) {
for (int j = L->length - 1; j >= i - 1; j--) {
L->location[j + 1] = L->location[j + 1];
}
L->location[i-1] = e;
L->length++;//长度+1
}
//若i在末尾直接插入
L->location [i - 1] = e;
L->length++;//长度+1
return OK;
}
//查找元素
int findElem(SqList L, Element e) {
for (int i = 0; i < L.length; i++) {
if (L.location[i] == e) {
return i + 1;//返回第i个元素
}
}
return ERROR;
}
//获取元素
Status getElem(SqList L, int i, Element* e) {
if (i < 1 || i>L.length )return ERROR;
e = L.location[i];//把第i各元素返回给Element类型数据
return OK;
}
//删除操作
Status deleElem(SqList* L, int i) {
if (L->length == 0)return ERROR;//此时为空表
if (i<1 || i>L->length) return ERROR;//位置不合理
//删除后面元素前移
for (int j = i; j < L->length;j++) {
L->location[j - 1] = L->location[j];
}
L->length--;
return OK;//删除成功
}
int main1() {
SqList L;
Element element=0;
int choice;
int index;//插入位置
while (OK) {
printf("---欢迎使用链表查询系统-----\n");
printf("--------1-初始化链表--------\n");
printf("--------2-插入链表元素------\n");
printf("--------3-查找元素----------\n");
printf("--------4-删除元素----------\n");
printf("--------5-获取元素----------\n");
printf("--------6-遍历元素----------\n");
printf("--------7-退出系统----------\n");
scanf("%1d", &choice);
switch (choice)
{
case 1:
//调用initiElem函数开始初始化
if (initiElem(&L) == NULL) {
printf("初始化失败!\n");
return ERROR;
}
printf("初始化成功!\n");
break;
case 2:
printf("请输入你想插入的元素(整数):\n");
scanf("%d", &element);
printf("请输入你想插入的位置:\n");
scanf("%d", &index);
if (insertElem(&L, index, element) == 0) {
printf("插入失败!\n");
break;
}
printf("插入成功!\n");
break;
case 3:
printf("请输入你想查找的元素(整数):\n");
scanf("%d", &element);
if (findElem(L,element) == 0) {
printf("查找失败\n");
break;
}
printf("该元素在第%d个位置\n", findElem(L,element));
break;
case 4:
printf("请输入你想删除的元素(位置):\n");
scanf("%d", &index);
if (deleElem(&L,index) == 0) {
printf("删除失败!\n");
break;
}
printf("删除成功!\n");
break;
case 5:
printf("请输入你想获取元素的位置:\n");
scanf("%d", &index);
if (getElem(L, index, &element) == 0) {
printf("获取失败!");
break;
}
printf("第%d的元素为 %d", index + 1, element);
break;
case 6:
if (L.length == 0) {
printf("为空表,无法遍历");
break;
}
for (int i = 0; i < L.length; i++) {
printf("%d\n", *(L.location+i));
}
break;
default:
break;
}
}
}
总结
优点
1.由于是根据下表查找数据,则数组(顺序表)查找速度快
时间复杂度O(1)
缺点
1.因为每次删除元素,或者插入数组时,每个数据都需要向后或者向前位移则平均时间复杂度为O(n)
,所以插入或删除速度慢
例题
26. 删除有序数组中的重复项
给你一个 非严格递增排列 的数组 nums
,请你原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums
中唯一元素的个数。
考虑 nums
的唯一元素的数量为 k
,你需要做以下事情确保你的题解可以被通过:
- 更改数组
nums
,使nums
的前k
个元素包含唯一元素,并按照它们最初在nums
中出现的顺序排列。nums
的其余元素与nums
的大小不重要。 - 返回
k
。
判题标准:
系统会用下面的代码来测试你的题解:
int[] nums = [...]; // 输入数组
int[] expectedNums = [...]; // 长度正确的期望答案
int k = removeDuplicates(nums); // 调用
assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
assert nums[i] == expectedNums[i];
}
如果所有断言都通过,那么您的题解将被 通过。
示例 1:
输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。
示例 2:
输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。
提示:
1 <= nums.length <= 3 * 104
-104 <= nums[i] <= 104
nums
已按 非严格递增 排列
int removeDuplicates(int* nums, int numsSize){
/*
快慢指针
*/
int slow = 1;//快指针
int fast = 1;
while(fast<numsSize){
if(nums[fast]!=nums[fast-1]){
nums[slow]=nums[fast];
++slow;
}
++fast;
}
return slow;
}
class Solution {
public int removeDuplicates(int[] nums) {
int p=0;
int q = 1;
//快慢指针 快指针不停地去寻找不同的值,然后替换慢指针的下一个位置
if(nums==null||nums.length==0)return 0;
while(q<nums.length){
if(nums[p]!=nums[q]){
if(q-p>1)nums[p+1]=nums[q];//判断
p++;
}
q++;
}
return p+1;
}
}
1. 两数之和
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9
输出:[0,1]
解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
示例 2:
输入:nums = [3,2,4], target = 6
输出:[1,2]
示例 3:
输入:nums = [3,3], target = 6
输出:[0,1]
提示:
2 <= nums.length <= 104
-109 <= nums[i] <= 109
-109 <= target <= 109
- 只会存在一个有效答案
进阶:你可以想出一个时间复杂度小于 O(n2)
的算法吗?
class Solution {
public int[] twoSum(int[] nums, int target) {
int[] numsSum = new int[2];
if(nums==null||nums.length<2)return numsSum;
int len = nums.length;
HashMap<Integer,Integer> hashMap = new HashMap<>();
for(int i=0;i<nums.length;++i){
hashMap.put(nums[i],i);
}
int temp=0;
for(int i=0;i<nums.length;++i){
temp = target - nums[i];
if(hashMap.containsKey(temp)&&hashMap.get(temp)!=i){
numsSum = new int[]{i, hashMap.get(temp)};
}
}
return numsSum;
}
}
优化
public int[] twoSum(int[] nums, int target) {
HashMap<Integer,Integer> hashMap = new HashMap<>();
for(int i=0;i<nums.length;++i){
if(hashMap.containsKey(target - nums[i])){
return new int[]{i, hashMap.get(target - nums[i])};
}
hashMap.put(nums[i],i);
}
return null;
}
}
27. 移除元素
153. 寻找旋转排序数组中的最小值
485. 最大连续 1 的个数
414. 第三大的数
2656. K 个元素的最大和
LCP 06. 拿硬币
2057. 值相等的最小索引
26. 删除有序数组中的重复项
2125. 银行中的激光束数量
27. 移除元素
[1431. 拥有最多糖果的孩子](
数据结构 顺序表(C语言 与 Java实现)以及部分练习题的更多相关文章
- 数据结构与算法之顺序表C语言实现
顺序表等相关概念请自行查阅资料,这里主要是实现. 注: 1.顺序表C语言实现: 2.按较简单的方式实现,主要帮助理解,可在此基础上修改,更加完善: 3.提供几个简单函数,可自行添加功能: 4.可用C+ ...
- hrbustoj 1545:基础数据结构——顺序表(2)(数据结构,顺序表的实现及基本操作,入门题)
基础数据结构——顺序表(2) Time Limit: 1000 MS Memory Limit: 10240 K Total Submit: 355(143 users) Total Accep ...
- hrbust-1545-基础数据结构——顺序表(2)
http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1545 基础数据结构——顺序表(2) ...
- 数据结构顺序表Java实现
Java实现顺序表算法:1:首先我们需要定义我们的接口,关于顺序表的一些基本的操作:顺序表中的操作都有增删改查. //List接口 public interface IList { //返回线性表的大 ...
- Java数据结构——顺序表
一个线性表是由n(n≥0)个数据元素所构成的有限序列. 线性表逻辑地表示为:(a0,a1,…,an-1).其中,n为线性表的长度,n=0时为空表.i为ai在线性表中的位序号. 存储结构:1.顺序存储, ...
- python算法与数据结构-顺序表(37)
1.顺序表介绍 顺序表是最简单的一种线性结构,逻辑上相邻的数据在计算机内的存储位置也是相邻的,可以快速定位第几个元素,中间不允许有空,所以插入.删除时需要移动大量元素.顺序表可以分配一段连续的存储空间 ...
- 数据结构顺序表中Sqlist *L,&L,Sqlist *&L
//定义顺序表L的结构体 typedef struct { Elemtype data[MaxSize]: int length; }SqList; //建立顺序表 void CreateList(S ...
- c数据结构 顺序表和链表 相关操作
编译器:vs2013 内容: #include "stdafx.h"#include<stdio.h>#include<malloc.h>#include& ...
- 数据结构顺序表删除所有特定元素x
顺序表类定义: template<class T> class SeqList : { public: SeqList(int mSize); ~SeqList() { delete[] ...
- 顺序表C语言版
#include <stdio.h> /* * 顺序表最多输入N个数 */ #define N 10 #define OK 1 #define ERROR -1 struct sequeu ...
随机推荐
- Linux基础-01:Linux命令的基本格式
2.1.1 命令提示符 在CentOS 7操作系统中,Linux命令提示符就像是你与电脑交流的一个小标志,告诉你系统已经准备好接受你的指令了. 它通常会显示在你打开的终端窗口或控制台的最前面. 让我们 ...
- Oracle ORA-12725 unmatched parentheses in regular expression
Oracle ORA-12725 unmatched parentheses in regular expression 简单来说就是正则表达式中的括号问题 这种一般就可以锁定使用正则的函数,例如 r ...
- 力扣525(java&python)-连续数组(中等)
题目: 给定一个二进制数组 nums , 找到含有相同数量的 0 和 1 的最长连续子数组,并返回该子数组的长度. 示例 1: 输入: nums = [0,1]输出: 2说明: [0, 1] 是具有相 ...
- 力扣237(java&python)-删除链表中的节点(中等)
题目: 有一个单链表的 head,我们想删除它其中的一个节点 node. 给你一个需要删除的节点 node .你将 无法访问 第一个节点 head. 链表的所有值都是 唯一的,并且保证给定的节点 n ...
- dubbogo 3.0:牵手 gRPC 走向云原生时代
作者 | 李志信 于雨来源|阿里巴巴云原生公众号 自从 2011 年 Dubbo 开源之后,被大量中小公司采用,一直是国内最受欢迎的 RPC 框架.2014 年,由于阿里内部组织架构调整,Dubbo ...
- 阿里云数据库开源重磅发布:PolarDB三节点高可用的功能特性和关键技术
简介:在3月2日的阿里云开源 PolarDB 企业级架构发布会上,阿里云数据库技术专家孟勃荣 带来了主题为<PolarDB 三节点高可用>的精彩演讲.三节点高可用功能主要为 PolarD ...
- Kettle on MaxCompute使用指南
简介: Kettle是一款开源的ETL工具,纯java实现,可以运行于Windows, Unix, Linux上运行,提供图形化的操作界面,可以通过拖拽控件的方式,方便地定义数据传输的拓扑.Kett ...
- [FAQ] Windows 终端 `git diff` 出现 LF 空格 ^M 符号, 处理方式
可能是终端内的换行配置和 IDE 当中的不一致. 比如 PHPStorm 的: Git 终端使用 git config core.autocrlf 查看是 true 还是 false. 是 tru ...
- [FE] nvm-windows: Microsoft/NPM/Google 推荐 Windows 的 Node.js 版本管理器, posix 的 nvm-sh/nvm
1. 到 github 下载 nvm-setup.zip 并安装. Releases · coreybutler/nvm-windows (github.com) 2. 安装一个版本的 nodejs. ...
- [FAQ] FinalCutPro 事件如何支持多个时间线
左侧是建立的事件,右侧是默认的项目(也就是时间线上的剪辑项目). 如果需要这个事件里再弄一个时间线(比如剪辑另一个版本),左侧的事件上右击新建项目: 另一个项目,在这上面可以继续时间线的创作,等于是选 ...