408数据结构学习强化——常见数据结构定义和算法总结(一)

简介: 408数据结构学习强化——常见数据结构定义和算法总结

.数组

1.1.将一个数组前后翻转

d6eefad9161c404ba2b7a72f8f2b7f4c.png

bool Delete_Min(int A[], n, &min) {
    if (!n) return false;    //数组长度为0,返回false
    int temp = INT_MAX, m;    //INT_MAX为int类型的最大值
    for (int i = 0; i < n; i++) {    //遍历数组,找到数组当前的最小元素
        if (A[i] < temp) {
            temp = A[i];    //更新数组最小值
            m = i;    //记录数组下标
        }
    }
    min = temp;    //min保存最小值
    A[m] = A[n - 1];    //m用数组中最后一个元素替换
    return true;
}

1.2.删除数组中值为x的元素

5d0005dde27f442cb56bea3cfae7c26a.png

int DeleteX(int A[], x, n){
    int i = 0, j = 0;
    for (i = 0; i < n; i++) {
        if (A[i] != x) {    //当前元素的值不为x
            A[j] = A[i];    //将其保存到数组下标为j的元素中
            j++;
        }
    }
    n = j;    
    return n;    //返回删除x后的数组元素个数
}

1.3.将两个有序数组合并成一个有序数组

9b3df95c179542c994fc309f9783494e.png

int* Merge(int A[], B[], lenA, lenB) {
    int *C = (int*)malloc((lenA + lenB) * sizeof(int));
    int a = 0, b = 0, c = 0;
    for (c = 0; a < lenA && b < lenB; c++) {    //选择两个数组中的较小值放入数组C中
        if (A[a] <= B[b]) C[c] = A[a++];
        else C[c] = B[b++];
    }
    while (a < lenA) C[c++] = A[a++];    //将剩余数组放入C中
    while (b < lenB) C[c++] = B[b++];
    return C;
}

1.4.真题bd99ceb964a943a8b2cf8fb35e95363e.png

void ans(int A[], n, p){
    int B[n], i, j;
    for (i = 0, j = p; j < n; i++, j++) B[i] = A[j];    //数组后部分前移
    for (j = 0; j < p; i++, j++) B[i] = A[j];    //数组前部分后移
    for (i = 0; i < n; i++) cout << B[i];    //输出循环前移后的数组
}

63e9f7fd08b448d08b08ae0714bc92d1.png

int res(int A[], int B[], int n){
    int i, j, k, mid;
    for (i = 0, j = 0, k = 0; k < n; k++){
        if (A[i] <= B[j]) {    //当前A数组的元素小,保存A[i]
            mid = A[i];
            i++;    
        } else {    //当前B数组的元素小,保存B[j]
            mid = B[j];
            j++;
        }
    }
    return mid;
}
void Qsort(int A[], L, R){
    if (L >= R) return;    //当前数组区间<= 1,返回
    随机选择数组中一个元素和A[L]交换    //快速排序优化,使得基准元素的选取随机
    int key = A[L], i = L, j = R;    //选择A[L]作为基准元素,i和j分别为左右指针
    while(i < j) {
        while (i < j && key < A[j]) j--;
        while (i < j && A[i] <= key) i++;
        if (i < j) swap(A[i], A[j]);    //交换A[i]和A[j]
    }
    swap(A[i], A[L]);
    Qsort(A, L, i - 1);    //递归排序左区间
    Qsort(A, i + 1, R);    //递归排序右区间
}
int ans(int A[], int B[], int n) {
    int C[2n], i, j;
    for (i = 0; i < n; i++) C[i] = A[i];    //复制数组A和数组B的元素
    for (j = 0; j < n; i++, j++) C[i] = B[j];
    Qsort(C, 0, 2n - 1);    //对数组C进行快速排序
    return C[n - 1];    //返回中位数
}

e24f9027d944449f9f267da69c9a9428.png

int ans(int A[], n){
    int count[n];
    for (int i = 0; i < n; i++) count[i] = 0;    //初始化count数组
    //遍历A数组,其元素的值作为count数组下标的元素+1,表示该元素在A数组中出现次数
    for (int i = 0; i < n; i++) count[A[i]]++;   
    for (int i = 0; i < n; i++) {    //当前元素出现次数符合主元素定义
        if (count[i] > n / 2) return i;    //返回i,即该元素的值
    }
    return -1;    //没有元素符合主元素定义
}

9fd06f5530b2430da410e14815da0fdd.png

int ans(int A[], n) {
    bool B[n + 2];    //B用来标记数组中出现的正整数
    for (int i = 0; i < n; i++) B[i] = false;    //初始化B数组
    for (int i = 0; i < n; i++) {
        if (A[i] > 0) B[A[i]] = true;    //该元素大于0,则在B数组中标记为已经出现
    }
    for (int i = 1; i < n; i++) {
        if (B[i] == false) return i;    //返回数组B中第一个false的元素下标
    }
}
void Qsort(int A[], L, R) {
  if (L >= R) return; //数组区间<= 1,返回
  随机选择数组中一元素和A[L]交换;//快排优化,使得基准元素的选取随机
  int key = A[L], i = L, j = R; //A[L]为基准元素,ij为左右指针
  while (i < j) {
    while (i < j && key < A[j]) j--;
    while (i < j && A[i] <= key) i++;
    if (i < j) Swap(A[i], A[j]);  //交换A[i]和A[j]
  }
  Swap(A[L], A[i]);
  Qsort(A, L, i - 1); //递归排序左区间
  Qsort(A, i + 1, R); //递归排序右区间
}
int ans(int A[], n) {
  Qsort(A, 0, n - 1); //快速排序
  int i = 0;
  while (A[i] <= 0) i++;  //找到数组中第一个大于0的元素
  if (n == i) return 1; //数组中没有元素大于0,返回1
  else {
    if (A[i] != 1) return 1;  //第一个整数不是1,则返回1
    else {    //第一个整数为1,找到数组中正整数第一个间断点
      int j = i + 1;
      while (j < n) {
                if (a[j] == a[j - 1]) j++;    //相邻元素相等
                else if (a[j] == a[j - 1] + 1) j++;    //相邻元素是连续数
                else return A[j - 1] + 1;    //相邻元素是间断点
            }//while
    }//else
  }//else
}

6ebfa00824c04488a0e1538e123a20f8.png

int Dis(int a, b, c){
    int res = abs(a - b) + abs(a - c) + abs(b - c);    //计算绝对值
    return res;
}
int Ans(int A[], int B[], int C[], int n1, int n2, int n3){
    int min = INT_MAX, i, j, k, temp;    //min取整型的最大值
    for (int i = 0; i < n1; i++) {    //循环遍历数组A
        for (int j = 0; j < n2; j++) {    //循环遍历数组B
            for (int k = 0; k < n3; k++) {    //循环遍历数组C
                temp = Dis(A[i], B[j], C[k]);
                if (temp < min) min = temp;    //当前元素之间的距离更小,更新最小距离
            }//for
        }//for
    }//for
    return min;    //返回最小距离
}

2.链表

2.1.链表的数据结构定义

2.1.1.单链表

2.1.1.单链表

typedef struct LNode {
    struct LNode *next;
    int data;
}LNode, *LinkList;

2.1.2.双链表

typedef struct LNode {
    struct LNode *prior, *next;
    int data;
}LNode, *LinkList;

2.2.链表的操作

2.2.1.头插法(插入到链表头)

void HeadInsert(LinkList &L, int key) {
    LNode *p = (LNode*)malloc(sizeof(LNode));
    p->data = key;
    p->next = L->next;
    L->next = q;
}

2.2.2.尾插法(插入到链表尾)

void TailInsert(LinkList &L, int key) {
    LNode *q = (LNode*)malloc(sizeof(LNode);
    q->data = key;
    q->next = NULL;
    LNode *p = L->next, *pre = L;
    while (!p) {
        pre = p;
        p = p->next;
    }
    pre->next = q;
}

2.2.3.链表逆置(头插法实现)

void Reverse(LinkList &L) {
    LNode *p = L->next, *q = NULL;
    L->next = NULL;    //将L表断开
    while (!p) {
        q = p->next;    //q指向p的下一个结点
        p->next = L->next;    //头插法
        L->next = p;
        p = q;
    }
}

2.2.4.链表的遍历

LNode *p = L->next;
while (!p) {
    visit(p);
    p = p->next;
}

2.2.5.链表的删除

void Delete(LinkList &L, int &key) {
    LNode *p = L->next, *pre = L;
    移动p和pre到指定结点    //pre指向p的前驱结点
    key = p->data;    //key保存p的data领
    pre->next = p->next;    //pre的next指针指向p的后继节点
    free(p);
}

2.3.链表算法题

2.3.1.删除值为x的结点

1.void DeleteX(LinkList &L, int x){
    LNode *p = L->next, *pre = L;
    while (p) {
        if (p->data == x) {    //当前元素值为x
            pre->next = p->next;
            free(p);
            p = pre->next;
        } else {    //当前元素值非x,p和pre向后移动
            p = p->next;
            pre = pre->next;
        }
    }
}

2.3.2.单链表就地逆置

99e7afe97aa04a699c22f929a0b6f198.png

void reverse(LinkList &L){
    LNode *p = L->next, *q;
    L->next = NULL;    //断链
    while (p) {
        q = p->next;    //q指向p的下一个结点
        p->next = L->next;    //头插法
        L->next = p;
        p = q;
    }
}

2.3.3.将链表排序83649d0dd1504382b5f534f74b959ff0.png

LNode *Sort(LinkList L) {
  LNode* p = (LNode*)malloc(sizeof(Lnode));
  p->next = NULL;
  LNode* t = L->next, * tpre = L, *min, *minpre, *r = p;
  int m = INT_MAX;
  while (t) {
    while (t) {    //遍历链表
      if (t->data < m) {  //更新最小值结点
        min = t;
        minpre = tpre;
        m = t->data;
      }//if
            tpre = t;
            t = t->next;
    }//while
    minpre->next = min->next; //将min从L中删除
    r->next = min;  //将min插入p
    r = min;  //r后移
    m = INT_MAX;  //重新初始化
    t = L->next;
    tpre = L;
  }//while
  r->next = NULL;
  return p;
}

2.3.4.拆分链表

87bccb5146f44a919002d0af76a41f96.png

LNode* (LinkList &L) {
    LNode *p = (LNode*)malloc(sizeof(LNode);
    p->next = NULL;    //p为新链的头结点
    LNode *q = L->next, *t = NULL, *r = L;
    r->next = NULL;    //r结点始终指向L的最后一个结点
    while (q) {
        t = q->next;
        r->next = q;    //奇数结点尾插法
        r = q;
        q = t;
        t = q->next;
        q->next = p->next;    //偶数节点头插法
        p->next = q;
        q = t;
    }
    r->next = NULL;    //将r的next指针置空
    return p;
}


相关文章
|
18天前
|
存储 算法 索引
【算法与数据结构】队列的实现详解
【算法与数据结构】队列的实现详解
|
1天前
|
设计模式 算法 Java
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
[设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
|
8天前
|
机器学习/深度学习 算法 前端开发
Scikit-learn进阶:探索集成学习算法
【4月更文挑战第17天】本文介绍了Scikit-learn中的集成学习算法,包括Bagging(如RandomForest)、Boosting(AdaBoost、GradientBoosting)和Stacking。通过结合多个学习器,集成学习能提高模型性能,减少偏差和方差。文中展示了如何使用Scikit-learn实现这些算法,并提供示例代码,帮助读者理解和应用集成学习提升模型预测准确性。
|
8天前
|
机器学习/深度学习 算法 Python
使用Python实现集成学习算法:Bagging与Boosting
使用Python实现集成学习算法:Bagging与Boosting
18 0
|
9天前
|
Python
python学习-函数模块,数据结构,字符串和列表(下)
python学习-函数模块,数据结构,字符串和列表
49 0
|
10天前
|
存储 机器学习/深度学习 算法
上机实验三 图的最小生成树算法设计 西安石油大学数据结构
上机实验三 图的最小生成树算法设计 西安石油大学数据结构
19 1
|
15天前
|
算法
【算法学习--字符串】(不含KMP算法)
【算法学习--字符串】(不含KMP算法)
|
18天前
|
算法 索引
【算法与数据结构】深入二叉树实现超详解(全源码优化)
【算法与数据结构】深入二叉树实现超详解(全源码优化)
|
18天前
|
存储 算法
【算法与数据结构】深入解析二叉树(二)之堆结构实现
【算法与数据结构】深入解析二叉树(二)之堆结构实现
|
1月前
|
传感器 算法 计算机视觉
基于肤色模型和中值滤波的手部检测算法FPGA实现,包括tb测试文件和MATLAB辅助验证
该内容是关于一个基于肤色模型和中值滤波的手部检测算法的描述,包括算法的运行效果图和所使用的软件版本(matlab2022a, vivado2019.2)。算法分为肤色分割和中值滤波两步,其中肤色模型在YCbCr色彩空间定义,中值滤波用于去除噪声。提供了一段核心程序代码,用于处理图像数据并在FPGA上实现。最终,检测结果输出到&quot;hand.txt&quot;文件。