顺序表模拟实现以及习题整理

顺序表实现:

#include "seqlist.h"
#include <stdlib.h>
#include <string.h>

//初始化
void seqListInit(seqlist* sl) {
	sl->_array = (DataType*)malloc(4 * sizeof(DataType));
	sl->_capacity = 4;
	sl->_size = 0;
}
//尾插
void seqListPushBack(seqlist* sl, DataType value) {
	/*checkCapacity(sl);
	sl->_array[sl->_size++] = value;*/
	seqListInsert(sl, sl->_size, value);
}
//尾删: 删除顺序表中的最后一个元素
void seqListPopBack(seqlist* sl) {
	//不需要释放空间
	/*if (sl->_size>0) {
		--sl->_size;
		}*/
	seqListErase(sl,sl->_size-1);
}
//头插
void seqListPushFront(seqlist* sl, DataType value) {
	//checkCapacity(sl);
	元素移动需要从后向前移动
	int end = sl->_size;
	//size_t end = sl->_size;
	//while (end > 0) {
	//	sl->_array[end] = sl->_array[end-1];
	//	--end;
	//}
	//sl->_array[0] = value;
	//++sl->_size;
	seqListInsert(sl,0,value);
}
//头删
void seqListPopFront(seqlist* sl) {
	注意元素覆盖的问题
	移动:从前向后移动
	//if (sl->_size) {
	//	size_t start = 1;
	//	//1->sl->_size-1 ---> 0~sl->-size-2
	//	while (start<sl->_size) {
	//		sl->_array[start - 1] = sl->_array[start];
	//		++start;
	//	}
	//	--sl->_size;
	//}
	seqListErase(sl, 0);
}

//在pos位置的前面插入一个数据value
void seqListInsert(seqlist* sl, size_t pos, DataType value) {

	//插入的位置必须合法
	if (pos <= sl->_size) {
		//检查容量是否够
		checkCapacity(sl);
		//移动元素
		size_t end = sl->_size;
		while (end > pos) {
			sl->_array[end] = sl->_array[end-1];
			--end;
		}
		sl->_array[pos] = value;
		++sl->_size;
	}
}
//删除pos位置的元素
void seqListErase(seqlist* sl, size_t pos) {
	if (pos<sl->_size) {
	//删除元素: 从前向后移动
	//移动的位置: pos+1~size-1 --->pos~size-2
		size_t start = pos+1;
		while ( start< sl->_size) {
			sl->_array[start-1] = sl->_array[start];
			++start;
		}
		--sl->_size;
	}
}
//查找
int seqlistFind(seqlist* sl, DataType value) {
	for (int i = 0; i < sl->_size;i++) {
		if (sl->_array[i] == value) {
			return i;
		}
		else {
			return -1;
		}
	}
}

void seqlistPrint(seqlist* sl) {
	for (int i = 0; i < sl->_size; i++) {
		printf("%d ", sl->_array[i]);
	}
	printf("\n");
}
void checkCapacity(seqlist* sl) {
	//增容 1.开更大空间 2.拷贝原有的内容 3.释放原有的空间
	//malloc 申请失败  返回NULL
	if (sl->_size == sl->_capacity) {
		sl->_capacity *= 2;
		1.开更大的空间
		//DataType* newArray = (DataType*)malloc(sl->_capacity*sizeof(DataType));
		2.拷贝原来的内容
		//memcpy(newArray,sl->_array,sl->_size*sizeof (DataType));
		3.释放原来的空间
		//free(sl->_array);
		//sl->_array = newArray;
		sl->_array = (DataType*)realloc(sl->_array, sizeof(DataType)*sl->_capacity);
	}
}

```c
#include <stdio.h>
#pragma once 

//动态顺序表
//typedef int DataType;
#define DataType int 
typedef struct seqlist{
	DataType* _array;
	//元素个数
	DataType _size;
	//容量: 当前可用的空间
	DataType _capacity;
}seqlist;
//顺序表初始化
void seqListInit(seqlist* sl);
//尾插
void seqListPushBack(seqlist* sl,DataType value);
//尾删
void seqListPopBack(seqlist* sl);
//头插
void seqListPushFront(seqlist* sl, DataType value);
//头删
void seqListPopFront(seqlist* sl);
//在pos位置的前面插入一个数据value
void seqListInsert(seqlist* sl,size_t pos,DataType value);
//删除pos位置的元素
void seqListErase(seqlist* sl, size_t pos);
//查找
int seqlistFind(seqlist* sl, DataType value);
//
void seqlistPrint(seqlist* sl);
//增容
void checkCapacity(seqlist* sl);
测试文件
#include "seqlist.h"
#include <stdio.h>
#include <stdlib.h>

//void test1() {
//	seqlist sl;
//	seqListInit(&sl);
//	seqListPushBack(&sl, 1);
//	seqListPushBack(&sl, 2);
//	seqListPushBack(&sl, 3);
//	seqlistPrint(&sl);
//	seqListPopBack(&sl);
//	seqlistPrint(&sl);
//	seqListPopBack(&sl);
//	seqlistPrint(&sl);
//	seqListPopBack(&sl);
//	seqlistPrint(&sl);
//}
void test2() {

	seqlist sl;
	seqListInit(&sl);
	seqListPushBack(&sl, 1);
	seqListPushBack(&sl, 2);
	seqListPushBack(&sl, 3);
	for (int i = 0; i < 10000;i++) {
		seqListPushFront(&sl,i);
	}
	seqlistPrint(&sl);

}
void test3() {
	seqlist sl;
	seqListInit(&sl);
	seqListPushBack(&sl, 1);
	seqListPushBack(&sl, 2);
	seqListPushBack(&sl, 3);
	seqlistPrint(&sl);

	seqListPopFront(&sl);
	seqlistPrint(&sl);
	seqListPopFront(&sl);
	seqlistPrint(&sl);
	seqListPopFront(&sl);
	seqlistPrint(&sl);

}

void test4() {
	seqlist sl;
	seqListInit(&sl);
	seqListPushBack(&sl, 3);
	seqListPushFront(&sl, 2);
	seqListPushFront(&sl, 1);
	seqlistPrint(&sl);
	seqListPushBack(&sl, 4);
	seqlistPrint(&sl);
	seqListPushBack(&sl, 5);
	seqlistPrint(&sl);
	seqListPushBack(&sl, 7);
	seqlistPrint(&sl);
	seqListPushBack(&sl, 9);
	seqlistPrint(&sl);
	seqListPushBack(&sl, 10);
	seqlistPrint(&sl);
	seqListInsert(&sl, 6, 8); //对应的是下标  下标前面的插入
	seqlistPrint(&sl);
	seqListInsert(&sl, 5, 6);
	seqlistPrint(&sl);
}
void test5() {
	seqlist sl;
	seqListInit(&sl);
	seqListPushBack(&sl, 3);
	seqListPushFront(&sl, 2);
	seqListPushFront(&sl, 1);
	seqListPushBack(&sl, 4);
	seqListPushBack(&sl, 5);
	seqlistPrint(&sl);

	seqListPopFront(&sl);
	seqlistPrint(&sl);
	seqListPopFront(&sl);
	seqlistPrint(&sl);

	seqListPopBack(&sl);
	seqlistPrint(&sl);
}

int main() {

	//test1();
	//test2();
	//test3();
	//test4();
	test5();
	system("color A");
    system ("pause");
    return 0;
}

习题整理

1.原地移除数组中的val,要求时间复杂度O(n),空间复杂度为O(1):
方法1: 在原数组的基础之上进行移除操作
#include <stdio.h>
#include <stdlib.h>

int removeNum(int arr[],int size,int value) {
	int i = 0,idx=0;
	for (int i = 0; i < size; i++) {
		if (arr[i] != value) {
			arr[idx] = arr[i];
			++idx;
		}
	}
	return idx;
}

int main () {
	int arr[] = { 1, 2, 4, 7, 6 };
	int size = sizeof(arr) / sizeof(arr[0]);
	int value = 4;
	int ret = removeNum(arr, size, value); //ret 代表返回的数组的长度
	printf("%d\n",ret);
	for (int i = 0; i < ret;i++) {
		printf("%d ",arr[i]);
	}
	printf("\n");
    system("color A");
    system ("pause");
    return 0;
}
方法2:申请一块新的内存空间来进行处理.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int removeNum(int arr[], int size, int value) {
	int* Newarr = (int*)malloc(size*sizeof(int));
	int i = 0, idx = 0;
	for (int i = 0; i < size; i++) {
		if (arr[i] != value) {
			Newarr[idx++] = arr[i];
		}
	}
	memcpy(arr,Newarr,sizeof(int)*idx);
	free(Newarr);
	return idx;
}

int main() {
	int arr[] = { 1, 2, 4, 7, 6 };
	int size = sizeof(arr) / sizeof(arr[0]);
	int value = 4;
	int ret = removeNum(arr, size, value); //ret 代表返回的数组的长度
	printf("数组中的个数: %d\n", ret);
	for (int i = 0; i < ret; i++) {
		printf("%d ", arr[i]);
	}
	printf("\n");
	system("color A");
	system("pause");
	return 0;
}

运行结果:
在这里插入图片描述

2.删除排序数组中的重复项.

方法1:

#include <stdio.h>
#include <stdlib.h>

int removeDuplicate(int arr[],int size) {
	int j = 1, i = 0, idx = 0;
	while (j < size) {
		arr[idx++] = arr[i];
		if (arr[i] != arr[j]) {
			++i;
			++j;		
		} else {
			找到下一个不同元素的位置
			while (arr[i] == arr[j] && j < size)  
				++j;
				i = j;
				++j;
		}
	}
	当j跳出数组的时候,最后一个元素肯定不重复,也要给复制过去
	if (i<size) {
		arr[idx++] = arr[i];
	}
	return idx;
}

int main() {
	int arr[] = { 1, 2, 4, 4, 6, 6, 7 };
	int size = sizeof(arr) / sizeof(arr[0]);
	int ret = removeDuplicate(arr, size); //ret 代表返回的数组的长度
	printf("不重复元素的个数为: %d\n", ret);
	for (int i = 0; i < ret; i++) {
		printf("%d ", arr[i]);
	}
	printf("\n");
	system("color A");
	system("pause");
	return 0;
}

运行结果:
在这里插入图片描述

方法2.常规思维 先将第一个元素找到,然后再依次与后面元素进行比较

#include <stdio.h>
#include <stdlib.h>

int  removeDuplicate(int nums[], int size) {
	if (size == 0) {
		return 0;
	}
	int temp = nums[0];
	int idx = 1;
	for (int i = 1; i < size; i++){
		if (nums[i] != temp) {
			temp = nums[i];
			nums[idx++] = temp;
		}
	}
	return idx;
}

int main() {
	int nums[] = { 1, 1, 2, 3, 4, 4, 5, 6, 6, 7, 8 };
	int size = sizeof(nums) / sizeof(nums[0]);
	int ret = removeDuplicate(nums, size);

	printf("不重复的元素个数为: %d\n", ret);
	for (int i = 0; i < ret;i++) {
		printf("%d ",nums[i]);
	}
	printf("\n");
	system("pause");
	return 0;
}

运行结果:
在这里插入图片描述

方法3: 快慢指针

#include <stdio.h>
#include <stdlib.h>

int removeDuplicate(int nums[], int size) {

	int s = 0;
	for (int f = 1; f < size; f++) {
		if (nums[s] != nums[f]) {
			nums[++s] = nums[f];
		}
	}
	return s + 1;
}

void Print(int nums[],int ret) {
	for (int i = 0; i < ret; i++) {
		printf("%d ", nums[i]);
	}
	printf("\n");
}

int main() {
	int nums[] = { 1, 1, 2, 3, 4, 4, 5, 6 };
	int size = sizeof(nums) / sizeof(nums[0]);
	int ret=removeDuplicate(nums, size);
	Print(nums, ret);
	system("pause");
	return 0;
}

运行结果:
在这里插入图片描述

3.合并两个有序数组

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void merge(int arr1[],int m, int arr2[],int n) {
	//未申请动态内存时,从后向前进行比较
	int idx = m + n - 1;
	while (m >0 && n >0) {
		if (arr1[m-1] >= arr2[n-1]) {
			arr1[idx--] = arr1[m - 1];
			--m;
		}
		else {
			arr1[idx--] = arr2[n - 1];
			--n;
		}
	}
	if (n>0) {
		memcpy(arr1,arr2,sizeof(int)*n);
	}
	for (int i = 0; i < 12; i++) {
		printf("%d ", arr1[i]);
	}
	printf("\n");
}

int main () {
	int arr1[] = { 1, 3, 3, 5, 7, 7 };
	int arr2[] = { 2, 4, 4, 5, 8, 9 };

	merge(arr1, 6, arr2,  6);
    system("color A");
    system ("pause");
    return 0;
}

运行结果:
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void merge(int arr1[],int m, int arr2[],int n) {
	int* newA = (int*)malloc(sizeof(int)*(m + n));
	int idx = 0;
	int n1 = 0;
	int n2 = 0;

	while (n1<m && n2<n ) {
		if (arr1[n1] <= arr2[n2]) {
			newA[idx++] = arr1[n1++];
		}
		else {
			newA[idx++] = arr2[n2++];	
		}
	}
	if (n1<m)
		memcpy(newA+idx, arr1 + n1, sizeof(int)*(m-n1));
	if (n2<n)
		memcpy(newA+idx, arr2 + n2, sizeof(int)*(n-n2));
	memcpy(arr1,newA,sizeof(int)*(m+n));
	free(newA);

}
void Print(int arr1[],int size) {
	for (int i = 0; i < size; i++) {
		printf("%d ", arr1[i]);
	}
	printf("\n");

}

int main () {
	int arr1[] = { 1, 3, 3, 5, 7, 7 };
	int arr2[] = { 2, 4, 4, 5, 8, 9 };
	int size1 = sizeof(arr1) / sizeof(arr1[0]);
	int size2 = sizeof(arr2) / sizeof(arr2[0]);

	merge(arr1, size1, arr2, size2);
	Print(arr1, size1+size2);
    system("color A");
    system ("pause");
    return 0;
}

运行结果:
在这里插入图片描述

基本思路:先将nums2中的元素插入到nums1中; 然后将其进行排序即可
class Solution {
public:
	void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {
		for (int i = 0; i < n; i++) {
			nums1[m + i] = nums2[i];
		}
		sort(nums1.begin(), nums1.end());
	}
}; 

4.旋转数组. 将数组中的元素向右移动k个元素的位置,其中k是一个非负数.

实例1: 输入[1,2,3,4,5,6,7] 和k等于3 输出: [5,6,71,2,3,4]

方法1: 基本思路:

1.先进行旋转一次
2.循环旋转k次

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
void RightRotateOne(int arr[],int size) {
	int end = size - 1;
	int start = arr[size-1];
	while (end>0) {
		arr[end] = arr[end - 1];
		--end;
	}
	arr[0] = start;
}
void RightRotateN(int arr[], int k1, int size) {
	for (int i = 1; i <= k1; i++) {
		RightRotateOne(arr, size);
		printf("向右旋转%d次: ",i);
		for (int i = 0; i < size; i++) {
			printf("%d ", arr[i]);
		}
		printf("\n");
	}
}

int main () {
	int arr[] = { 1, 2, 3, 4, 5, 6, 7 };
	int size = sizeof(arr) / sizeof(arr[0]);
	int k = 0;
	printf("请输入向右旋转的次数: ");
	scanf("%d",&k);
	RightRotateN(arr,k,size);

    system("color A");
    system ("pause");
    return 0;
}

运行结果:
在这里插入图片描述

方法2: 基本思路:

1.先根据k分成前后两部分的旋转
2.然后在进行数组整体的旋转

#include <stdio.h>
#include <stdlib.h>

void reverseOne(int* arr,int left,int right) {
	while (left<right) {
		//int temp = arr[right];
		//arr[right] = arr[left];
		//arr[left] = temp;
		swap(arr[left], arr[right])
		++left;
		--right;
	}
}

void reverseN(int arr[],int size,int k) {
	reverseOne(arr, 0, size - 1 - k); //前半部分旋转
	reverseOne(arr, size - k,size-1); //后半部分旋转
	reverseOne(arr, 0, size - 1); //整体旋转
}
void Print(int arr[], int size) {
	for (int i = 0; i < size; i++) {
		printf("%d ", arr[i]);
	}
	printf("\n");
}

int main() {
	int arr[] = { 1, 2, 3, 4, 5, 6, 7 };
	int size = sizeof(arr) / sizeof(arr[0]);
	int k = 3;
	reverseN(arr,size,k);
	Print(arr,size);
	system("color A");
	system("pause");
	return 0;
}

运行结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值