赞
踩
静态分配内存及初始化
#include<stdio.h>
#include<stdlib.h>
#define Maxsize 100
//静态
typedef struct sqlist {
int data[Maxsize];
int length;
}SqList;
void InitList(SqList& L) {
L.length = 0; //顺序表的初始长度为0
}
动态分配内存及初始化
//动态
typedef struct {
int* data; //指示动态分配数组的指针
int MaxSize; //顺序表的最大容量
int length; //顺序表的当前长度
}SeqList;
void InitList(SeqList& L) {
L.data = (int*)malloc(Maxsize * sizeof(int));
L.length = 0;
L.MaxSize = Maxsize;
}
//对顺序表L进行遍历并输出每个数据元素的数据值
void print(SqList &L){
for(int i=0;i<L.length;i++){
printf("%d",L.data[i]);
}
}
int search_e(SqList L, int e) {
for (int i = 0; i < L.length; i++) {
if (e == L.data[i]) {
return i;
}
}
return -1;
}
//假设有一个顺序表 L,其存储的所有数据元素均为正数,查找 L 中第 i 个数据元素并返回其值。
int Get_i(SqList L, int i) {
if (i >= 1 && i <= L.length) {
return L.data[i - 1];
}
return -1;//越界
}
①注意越界的判断
//设计一个高效算法,将顺序表 L 的所有元素逆置,要求算法的空间复杂度为 O(1)
void Reverse(SqList& L) {
int temp;
for (int i = 0; i < L.length/2; i++) {
temp = L.data[i];
L.data[i] = L.data[L.length - i - 1];
L.data[L.length - i - 1] = temp;
}
}
//在顺序表 L 的第 i 个位置插入新元素 e。若 i 的输入不合法,则返回 false,表示插入失败;否则,将第 i 个元素及 //其后的所有元素依次往后移动一个位置,腾出一个空位置插入新元素 e,顺序表长度增加 1,插入成功,返回 true。 bool Insert(SqList &L, int i, int e) { if (i<1 || i>L.length+1) { return false; } if (L.length == Maxsize) { return false; } for (int j = L.length; j > i-1; j--) { L.data[j] = L.data[j - 1]; } L.data[i - 1] = e; L.length++; return true; }
分析
先找出位置
插入元素
注意:要返回插入元素位置,i的定义要放在for循环外
举例(从后往前移动元素,第一行为顺序表,第二行为下标)
①假设x=5,即i=3,初始j=4,判断移动一次,故判断条件为j>i或者j>=i+1
②假设x=3,即i=2,初始i=4,判断移动两次,第一次移动条件j=4,i=2,第二次移动j=3,i=2,故判断条件为j>i或者j>=i+1
综上,判断条件为j>i或者j>=i+1
int Insert(SqList &L,int x){ int i;//定义变量 i 记录元素 x 插入位置 for(i=0; i<L.length; i++){ if(L.data[i]>x){ break; } } //也可以换成for(i=0; i<L.length,L.data[i]<=x; i++); //自己模拟j的条件(易错) for(j=L.length;j>i;j--){ L.data[j]=L.data[j-1]; } L.data[i]=x; L.length++; return i; }
分析
注意i是位置,和下标不一样
被删元素赋给引用变量 e
举例
位置 1 2 3 4 5
元素 2 5 1 3 4
下标 0 1 2 3 4
删除第2个位置,i=2,L.length=4,下标为1,要移动两次(j=2,j=3),判断条件为j<L.length
最后别忘了顺序表长度改变
bool ListDelete(SqList &L, int i, int &e){
if(i<1||i>L.length){
return false;
}
e=L.data[i-1];
for(int j=i; j<L.length; j++){
//后面赋值给前面
L.data[j-1]=L.data[j];
}
L.length--;
return ture;
}
分析
由于最后需要返回被删元素的值,因此需要有个变量对最小值进行保存,然后删除操作过程中,最小值被删除,此后如果没有保存最小元素的变量,则找不到最小值。
int Delete_min(SqList &L)[ if(L.length==0){ return 0; } //查找最小值 int min=L.data[0],pos=0; for(int i=1;i<L.length;i++){ if(L.data[i]<min){ min=L.data[i]; pos=i; } } //删除操作,首先定义 //j<L.length-1可以自己模拟出,假设长度为五,假设最小值时,i=pos=3,另j=i,说明只需要移动一次即可,判断条件 for(int j=pos; j<L.length-1;j--){ L.data[j]=L.data[j+1]; } //减少长度 L.length--; return min; ]
法一:
void Delete_all_x(SqList &L,int x){
int k=0;
for(int i=0;i<L.length;i++){
if(L.data[i]==x){
//应该删除
k++;
}
else{
//重点
L.data[i-k]=L.data[i];
}
}
L.length=L.length-k;
}
法二:
思路:将顺序表需要保存的元素理解为排队,直接用一个变量记录排队位置,
void Delete_all_x(SqList &L,int x){
int k=0;
for(int i=0; i<L.length; i++){
if(L.data[i]!=x){
//需要保留
L.data[k]=L.data[i];
k++;
}
}
//不是k+1,因为排队结束会执行k++的操作
L.length = k;
}
改成while循环也类似:
void Delete_all_x(SqList &L,int x){
int k=0;
int i=0;
while(i<L.length){
if(L.data[i]!=x){
k++;
}
i++;
}
//不是k+1,因为排队结束会执行k++的操作
L.length = k;
}
法一:
bool Del(SqList &L,int s,int t){
if(s>=t||L.length==0) //若 s 或 t 输入不合法或顺序表为空,则返回 false
return false;
int k=0; //k 用来记录要删除元素的数量,初始时为 0
for(int i=0;i<L.length;i++){ //遍历顺序表 L
if(L.data[i]>=s&& L.data[i]<=t) //若元素符合删除条件则 k 加一
k++;
}
else{ //若元素需保留则前移 k 个位置
L.data[i-k]= L.data[i];
}
L.length= L.length-k; //更新顺序表长度
return true; //执行结束返回 true
}
法二
bool Del(SqList &L,int s,int t){
if(s>=t||L.length==0) //若 s 或 t 输入不合法或顺序表为空,则返回 false
return false;
int j=0; //j 用来记录保留元素的排队位置
for(int i=0;i<L.length;i++){ //遍历顺序表 L
if(L.data[i]<s||L.data[i]>t){ //判断此次遍历到的元素是否为保留元素
L.data[j]=L.data[i]; //是保留元素则过去排队
j++; //新元素排队后需更新排队位置
}
}
L.length= j; //更新顺序表长度
return true; //执行结束返回 true
}
void Del_Same(SqList &L){
int j=1; // j 用来记录保留元素的排队位置
for(int i=1;i<L.length;i++){ //遍历顺序表 L
if(L.data[i]!=L.data[j-1]){ //判断此次遍历到的元素是否为保留元素
L.data[j]=L.data[i]; //是保留元素则过去排队
j++; //新元素排队后需更新排队位置
}
}
L.length=j; //更新顺序表长度
}
bool Del_s_t(SqList &L,int s,int t){ if(s>=t||L.length==0){ //若 s 或 t 输入不合法或顺序表为空则返回 false return false; } int i,j; //定义两个变量 i 和 j 负责记录待删元素的起始位置和结束位置 for(j=0;j<L.length&&L.data[j]<s;j++); //寻找待删元素起始位置 if(j==L.length){ //若顺序表中所有元素都比 s 小则没有要删元素 return false; } for(i=j;i<L.length&&L.data[i]<=t;i++); //寻找待删元素的结束位置 for(;i<L.length;i++,j++){ //将结束位置后的保留元素前移至起始位置 L.data[j]=L.data[i]; } L.length=j; //更新顺序表长度 return true; //执行结束则返回 true }
bool Merge(SeqList A, SeqList B, SeqList& C) { if (A.length + B.length > C.Maxsize) //判断 C 存储空间是否能容纳 A 和 B return false; int i = 0, j = 0, k = 0; //定义三个遍历指针,分别遍历 ABC while (i < A.length && j < B.length) { //只有 A 和 B 都没遍历完才可以继续循环 if (A.data[i] <= B.data[j]) { //若 A 表中值更小则 A 表中遍历元素赋值给 C 表 C.data[k] = A.data[i]; k++; //更新 C 表元素插入位置 i++; //更新 A 表遍历位置 } else { //若 B 表中值更小则 B 表中遍历元素赋值给 C 表 C.data[k] = B.data[j]; k++; //更新 C 表元素插入位置 j++; //更新 B 表遍历位置 } } while (i < A.length) { //若循环结束后 A 还有未遍历元素则顺序赋值给 C C.data[k] = A.data[i]; k++; i++; } while (j < B.length) { //若循环结束后 B 还有未遍历元素则顺序赋值给 C C.data[k] = B.data[j]; k++; j++; } C.length = k; //更新 C 表长度 return true; //执行结束返回 true }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。