第九章 排序【数据结构】【精致版】
第九章 排序【数据结构】【精致版】
- 前言
- 版权
- 第九章 排序
- 9.1 概述
- 9.2 插入类排序
- 9.2.1 直接插入排序
- **1-直接插入排序.c**
- 9.2.2 折半插入排序
- **2-折半插入排序.c**
- 9.2.3 希尔排序
- 9.3 交换类排序
- 9.3.1冒泡排序
- **4-冒泡排序.c**
- 9.3.2 快速排序
- **5-快速排序.c**
- 9.4 选择类排序
- 9.4.1 简单选择排序
- **6-简单选择排序.c**
- 9.4.2 树形选择排序
- 9.4.3 堆排序
- **7-堆排序.c**
- 9.5 归并类排序
- 9.5.1 二路归并排序
- **8- 二路归并排序.c**
- 9.5.2自然归并排序
- **9-自然归并排序.c**
- 9.6 分配类排序
- 9.6.1 多关键字排序
- **10-多关键字排序.c**
- 9.6.2 链式基数排序
- **11-链式基数排序.c**
- 9.7 外部排序
- 9.7.1置换选择排序
- 9.7.2多路归并外排序
- 9.8 算法总结
- 最后
前言
2023-11-7 16:23:34
以下内容源自《【数据结构】【精致版】》
仅供学习交流使用
版权
禁止其他平台发布时删除以下此话
本文首次发布于CSDN平台
作者是CSDN@日星月云
博客主页是https://jsss-1.blog.csdn.net
禁止其他平台发布时删除以上此话
第九章 排序
9.1 概述
记录序列的数据类型描述如下
#define MAXSIZE 1000 //假设的文件长度,即待排序的记录数目
typedef int KeyType; //假设的关键字类型
typedef int OtherType;
typedef struct{KeyType key;//关键字项OtherType other_data;//其他数据项,类型OtherType依赖于具体应用而定义
}RecordType; //记录类型
typedef struct{RecordType r[ MAXSIZE+1];int length;//序列长度,即记录个数
}RecordList; //记录序列类型,即顺序表类型RecordList create(int nums[],int n){RecordList L;L.length=n;for(int i=1;i<=n;i++){RecordType t={nums[i],0};L.r[i]=t;}return L;
}void print(RecordList L){int n=L.length;for(int i=1;i<=n;i++){printf("%d ",L.r[i].key);}printf("\n");
}
9.2 插入类排序
9.2.1 直接插入排序
1-直接插入排序.c
#include <stdio.h>
#include "0-RecordList.h"// 【算法9-1】直接插入排序
RecordList insertSort(RecordList L){for (int i = 2; i <= L.length; i++){L.r[0] = L.r[i]; // 监视哨备份待查记录int j;for (j = i - 1; L.r[0].key < L.r[j].key; j--){L.r[j + 1] = L.r[j]; // 记录后移}L.r[j + 1] = L.r[0]; // 插入正确位置}return L;
}// 待插记录已是当前有序的最大记录,不需要后移排序
// 【算法9-2】改进的直接插入排序
RecordList insertSortPlus(RecordList L){for (int i = 2; i <= L.length; i++){if (L.r[i].key < L.r[i - 1].key){ // 如果不小于,就是待插记录已是当前有序的最大记录L.r[0] = L.r[i]; // 监视哨备份待查记录int j;for (j = i - 1; L.r[0].key < L.r[j].key; j--){L.r[j + 1] = L.r[j]; // 记录后移}L.r[j + 1] = L.r[0]; // 插入正确位置}}return L;
}
int main(){int n=8;int nums[9]={-1,33,12,25,46,33,68,19,80};//0号不存储元素 RecordList L=create(nums,n);print(L);//33 12 25 46 33 68 19 80print(insertSort(L)); //12 19 25 33 33 46 68 80 print(insertSortPlus(L)); //12 19 25 33 33 46 68 80}
9.2.2 折半插入排序
2-折半插入排序.c
#include <stdio.h>
#include "0-RecordList.h"//【算法9-3】折半插入排序
//因为插入到有序列中,有折半快速找到位置
RecordList biInsertSort(RecordList L){for (int i = 2; i <=L.length ; i++) {if(L.r[i].key<L.r[i-1].key){//如果不小于,就是待插记录已是当前有序的最大记录L.r[0]=L.r[i];//监视哨备份待查记录//折半查找nums[i]插入位置int low=1;int high=i-1;while (low<high){int mid=(low+high)/2;if(L.r[0].key<L.r[mid].key){high=mid-1;}else{low=mid+1;}}for (int j = i-1; j>=low; j--) {L.r[j+1]=L.r[j];//记录后移}L.r[low]=L.r[0];//插入正确位置}}return L;
}
int main(){int n=8;int nums[9]={-1,33,12,25,46,33,68,19,80};//0号不存储元素 RecordList L=create(nums,n);print(L);//33 12 25 46 33 68 19 80print(biInsertSort(L)); //12 19 25 33 33 46 68 80 }
9.2.3 希尔排序
#include <stdio.h>
#include "0-RecordList.h"#include <stdio.h>
#include "0-RecordList.h"//【算法9-4】希尔排序
//最小增量排序
void shellInsert(RecordList* L,int dk){for (int i = dk+1; i<=L->length ; i++) {if(L->r[i].key<L->r[i-1].key){//如果不小于,就是待插记录已是当前有序的最大记录L->r[0]=L->r[i];//监视哨备份待查记录int j;for (j = i-dk; j>0&&L->r[0].key<L->r[j].key; j-=dk) {L->r[j+dk]=L->r[j];//记录后移}L->r[j+dk]=L->r[0];//插入正确位置}}
}
//dlta 增量序列
void shellSort(RecordList* L,int dlta[],int t){//t为增量序列的长度for (int k=0;k<t;k++){shellInsert(L,dlta[k]);}
}
int main(){int n=8;int nums[9]={-1,46,25,68,33,33,19,12,80};//0号不存储元素 RecordList L=create(nums,n);print(L);//46 25 68 33 33 19 12 80// int dlta[3]={4,2,1};int dlta[3]={7,3,1};int t=3;shellSort(&L,dlta,t); print(L);//12 19 25 33 33 46 68 80
}
9.3 交换类排序
9.3.1冒泡排序
4-冒泡排序.c
#include <stdio.h>
#include "0-RecordList.h"//【算法9-5】冒泡排序
RecordList bubbleSort(RecordList L){for (int i = 1; i <= L.length; i++) {for (int j = 1; j <=L.length-i ; j++) {if(L.r[j].key>L.r[j+1].key){RecordType temp=L.r[j];L.r[j]=L.r[j+1];L.r[j+1]=temp;}}}return L;
}//【算法9-6】改进冒泡排序
//如已排好序,直接跳出
RecordList bubbleSortPlus(RecordList L){int flag=1;for (int i = 1; i <= L.length&&flag; i++) {flag=0;for (int j = 1; j <=L.length-i ; j++) {if(L.r[j].key>L.r[j+1].key){RecordType temp=L.r[j];L.r[j]=L.r[j+1];L.r[j+1]=temp;flag=1;}}}return L;
}
int main(){int n=8;int nums[9]={-1,46,25,68,33,33,19,12,80};//0号不存储元素 RecordList L=create(nums,n);print(L);//46 25 68 33 33 19 12 80print(bubbleSort(L)); //12 19 25 33 33 46 68 80 print(bubbleSortPlus(L)); //12 19 25 33 33 46 68 80 }
9.3.2 快速排序
5-快速排序.c
#include <stdio.h>
#include "0-RecordList.h"
//【算法9-7】一趟快速排序
int QKPass(RecordList* L,int low,int high){L->r[0]=L->r[low];//枢轴while(low<high){while (low<high&&L->r[high].key>=L->r[0].key) --high;L->r[low]=L->r[high];while (low<high&&L->r[low].key<L->r[0].key) ++low;L->r[high]=L->r[low];}L->r[low]=L->r[0];return low;
}//【算法9-8】快速排序
void QKSort(RecordList* L,int low,int high){int pos;if (low<high){pos=QKPass(L, low,high);QKSort(L, low,pos-1);QKSort(L, pos+1,high);}
}
int main(){int n=8;int nums[9]={-1,46,68,12,25,33,80,19,33};//0号不存储元素 RecordList L=create(nums,n);print(L);//46 68 12 25 33 80 19 33 QKSort(&L,1,L.length); print(L);//12 19 25 33 33 46 68 80}
9.4 选择类排序
9.4.1 简单选择排序
6-简单选择排序.c
#include <stdio.h>
#include "0-RecordList.h"//【算法9-9】简单选择排序
RecordList selectSort(RecordList L){for (int i = 1; i <= L.length; i++) {int k=i;for (int j = i+1; j <=L.length ; j++) {if (L.r[j].key<L.r[k].key){//k是擂台k=j;}}if (k!=i){RecordType temp=L.r[i];L.r[i]=L.r[k];L.r[k]=temp;}}return L;}
int main(){int n=8;int nums[9]={-1,33,68,46,33,25,80,19,12};//0号不存储元素 RecordList L=create(nums,n);print(L);//33 68 46 33 25 80 19 12print(selectSort(L)); //12 19 25 33 33 46 68 80 }
9.4.2 树形选择排序
9.4.3 堆排序
7-堆排序.c
#include <stdio.h>
#include "0-RecordList.h"//【算法9-10】堆的筛选
void HeapAdjust(RecordList* L,int s,int m){//已知L[s..m]中记录的关键字除L[s]之外均满足堆的定义//本函数调整L[s]的关键字,使L[s..m]成为小顶堆RecordType t=L->r[s];for(int j=2*s;j<=m;j*=2){//沿key较小的孩子结点向下筛选if(j<m&&L->r[j].key>L->r[j+1].key){j++;//j为key较小的记录的下标}if(t.key<=L->r[j].key){break;}//t应该插入位置sL->r[s]=L->r[j];s=j;}L->r[s]=t;
}
//【算法9-11】建立初始堆
void CreatHeap(RecordList* L){int len=L->length;for (int i=len/2;i>=1;i--){HeapAdjust(L,i, len);}
}
//【算法9-12】堆排序
void HeapSort(RecordList* L){CreatHeap(L);int len= L->length;for (int i = len; i >=2 ; i--) {L->r[0]=L->r[1];L->r[1]=L->r[i];L->r[i]=L->r[0];HeapAdjust(L,1,i-1);}
}
int main(){int n=8;int nums[9]={-1,46,12,33,72,68,19,80,33};//0号不存储元素 RecordList L=create(nums,n);print(L);//46 12 33 72 68 19 80 33 HeapSort(&L); print(L);//80 72 68 46 33 33 19 12
}
9.5 归并类排序
9.5.1 二路归并排序
8- 二路归并排序.c
#include <stdio.h>
#include "0-RecordList.h"void Merge(RecordList* ,RecordList* ,int ,int ,int );//【算法9-13】二路归并排序
void MergeSort(RecordList* L,RecordList* CopyL,int left,int right){//对上下限值分别为left和right的记录序列L进行归并排序//其中copyL为同类型的记录,由于复制保存原记录序列int middle;if(left<right){middle=(left+right)/2;//找中间位置进行划分MergeSort(L,CopyL,left,middle);//对左半部分进行递归归并排序MergeSort(L,CopyL,middle+1,right);//对右半部分进行递归 归并排序Merge(L,CopyL,left,right,middle);//进行归并}
}//【算法9-14】二路归并排序
void Merge(RecordList* L,RecordList* CopyL,int left,int right,int middle){int i,p1,p2;for (i=left;i<=right;i++){//用copyL记录临时保存待排序记录序列CopyL->r[i]=L->r[i];}p1=left;//左半部分有序记录的起始位置p2=middle+1;//右半部分有序记录的起始位置i=left;//左半部分开始进行归并while(p1<=middle&&p2<=right){//取两个有序半区中关键字较小的记录if (CopyL->r[p1].key<=CopyL->r[p2].key){L->r[i]=CopyL->r[p1];//去较小的记录放到合并后的记录序列中p1++;} else{L->r[i]=CopyL->r[p2];p2++;}i++;}//剩下的序列无论是左半部分还是右半部分都直接复制到合并后的记录序列中while (p1<=middle){L->r[i]=CopyL->r[p1];i++;p1++;}while (p2<=middle){L->r[i]=CopyL->r[p2];i++;p2++;}}int main(){int n=8;int nums[9]={-1,46,12,33,72,68,19,80,33};//0号不存储元素 RecordList L=create(nums,n);print(L);//46 12 33 72 68 19 80 33RecordList CopyL=create(nums,n);MergeSort(&L,&CopyL,0,n); print(L);//12 19 33 33 46 68 72 80
}
9.5.2自然归并排序
9-自然归并排序.c
#include <stdio.h>
#include <stdlib.h>
#include "0-RecordList.h"//【算法9-15】自然归并排序
//将两个有序的子序列R[low..m]和R[m+1..high]归并成一个有序的子序列R[low..high]
void Merge(RecordType* R,int l,int m,int r){int i=l,j=m+1,p=0,q;RecordType *R1;R1=(RecordType*) malloc((r-l+1)*sizeof(RecordType));if(!R1) return;//申请空间失败 while (i<=m&&j<=r){//取两个有序半区中关键字较小的记录if(R[i].key<=R[j].key){R1[p++]=R[i++];}else {R1[p++]=R[j++];}}//剩下的序列无论是左半部分还是右半部分都直接复制到合并后的记录序列中if (i>m){for (q = j; q <=r ; q++) {R1[p++]=R[q];}}else {for (q=i;q<=m;q++){R1[p++]=R[q];}}for (p=0,i=l;i<=r;p++,i++){R[i]=R1[p];//归并完成后将结果复制回R[low..high]}
}
void NatureMergeSort(RecordType R[],int n){int i,sum,low,mid,high;while (1){i=0;sum=1;while (i<n-1){low=i;while (i<n-1&&R[i].key<R[i+1].key){ i++; }mid=i++;while (i<n-1&&R[i].key<R[i+1].key){ i++; }high=i++;if (i<=n){Merge(R,low,mid,high);sum++;}}if (sum==1) break;}}
int main(){int n=8;int nums[9]={-1,12,24,5,8,3,9,11,7};//0号不存储元素 RecordList L=create(nums,n);print(L);//12 24 5 8 3 9 11 7RecordList CopyL=create(nums,n);NatureMergeSort(L.r,9); print(L);//3 5 7 8 9 11 12 24
}
9.6 分配类排序
9.6.1 多关键字排序
10-多关键字排序.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <time.h>
/*
Heart 红桃
Spade 黑桃
club 梅花
diamond 方块
*/
//花色的枚举类
typedef enum color{D=1,C,S,H
}Color;
//扑克的定义
typedef struct card{Color color;int num;
}Card;
//输出花色
void printColor(Color c){switch(c){case H: printf("红桃");break;case S: printf("黑桃");break;case C: printf("梅花");break;case D: printf("方块");break;}
}
//输出扑克
void printCard(Card card){printColor(card.color);printf("%-2d",card.num);
} //创建一幅扑克
void creatCards(Card cards[52]){ int colors[4]={D,C,S,H};int nums[13]={1,2,3,4,5,6,7,8,9,10,11,12,13};int n=0;for(int i=0;i<4;i++){for(int j=0;j<13;j++){Card card;card.color=colors[i];card.num=nums[j];cards[n]=card; n++; }}
// printCards(cards);
}
//洗牌
void shuffleCards(Card cards[52]){ srand((unsigned)time(NULL));//用srand()函数来重新播种,用time来充当随机数种子 creatCards(cards); //交换52次 for (int i=0;i<52;i++){int r1=rand()%52;//rand()函数产生的随机数是伪随机数 ,和种子有关 int r2=rand()%52;//交换两张牌 Card temp=cards[r1];cards[r1]=cards[r2];cards[r2]=temp;}}
//打印扑克牌
void printCards(Card cards[52]){for(int i=0;i<52;i++){printCard(cards[i]);printf(" ");if(i%13==12){printf("\n");}}
}
//按最高位优先法MSD排序 花色从小到大 数值从小到大
void sortCardsWithMSD(Card cards[52]){printf("按最高位优先法LSD排序 \n"); //首先按照花色将整副牌分为4组(每组13张牌)Card cardsByColor[4][13];int cardColorCount[4]={0}; //一个计数器数组,用来记录每组花色加入了多少 for (int i=0;i<52;i++){int index=cards[i].color-1; //面值从1开始,索引是从0开始的 cardsByColor[index][cardColorCount[index]]=cards[i];cardColorCount[index]++; }
// printf("测试1\n");
// for(int i=0;i<4;i++){
// for(int j=0;j<13;j++){
// printCard(cardsByColor[i][j]);
// }
// printf("\n");
// }//然后每组在按照面值从小到大进行排序 (选择排序) for(int i=0;i<4;i++){ for(int j=0;j<13;j++){int m=j; for(int k=j+1;k<13;k++){if(cardsByColor[i][k].num<cardsByColor[i][m].num){m=k;}}if(m!=j){ Card temp=cardsByColor[i][j];cardsByColor[i][j]=cardsByColor[i][m];cardsByColor[i][m]=temp;}} }
// printf("测试2\n");
// for(int i=0;i<4;i++){
// for(int j=0;j<13;j++){
// printCard(cardsByColor[i][j]);
// }
// printf("\n");
// }int n=0;//最后将这4组牌收集到一起就是按照花色和面值排好序的有序序列 for(int i=0;i<4;i++){for(int j=0;j<13;j++){cards[n]=cardsByColor[i][j];n++;} }
}
//按最低位优先法LSD排序 花色从小到大 数值从小到大
void sortCardsWithLSD(Card cards[52]){printf("按最低位优先法LSD排序 \n"); //第一步 先按照面值大小从小到大将整副牌分为13组(每组4张牌) Card cardsByNum[13][4]; int cardNumCount[13]={0};//一个计数器数组,用来记录每组面值加入了多少 for (int i=0;i<52;i++){int index=cards[i].num-1; //面值从1开始,索引是从0开始的 cardsByNum[index][cardNumCount[index]]=cards[i]; cardNumCount[index]++; } // printf("测试1\n");
// for(int i=0;i<13;i++){
// for(int j=0;j<4;j++){
// printCard(cardsByNum[i][j]);
// }
// printf("\n");
// }//第二步 然后将每组牌按照面值的大小收集到一起 从小到大 Card CollectByNum[52]; int n=0;for(int i=0;i<13;i++){for(int j=0;j<4;j++){CollectByNum[n]=cardsByNum[i][j];n++;} }
// printf("测试2\n");
// printCards(CollectByNum);//第三步 再对这些牌按照花色摆成4组,每组13张牌 Card cardsByColor[4][13];int cardColorCount[4]={0}; //一个计数器数组,用来记录每组花色加入了多少 for (int i=0;i<52;i++){int index=CollectByNum[i].color-1;cardsByColor[index][cardColorCount[index]]=CollectByNum[i];cardColorCount[index]++; }
// printf("测试3\n");
// for(int i=0;i<4;i++){
// for(int j=0;j<13;j++){
// printCard(cardsByColor[i][j]);
// }
// printf("\n");
// }n=0;//第四步 最后再把4组牌按花色的次序收集到一起就是按照花色和面值排好序的有序序列 for(int i=0;i<4;i++){for(int j=0;j<13;j++){cards[n]=cardsByColor[i][j];n++;} }
// printf("4");}void sortCardsWithBinSort(Card cards[52]){printf("按桶排序 \n"); //首先按照花色将整副牌分为4组(每组13张牌) Card cardsByBin[4][13];//然后每组在按照面值从小到大进行排序 (桶排序)for (int n=0;n<52;n++){int i=cards[n].color-1;int j=cards[n].num-1;cardsByBin[i][j]=cards[n]; } int n=0;//最后将这4组牌收集到一起就是按照花色和面值排好序的有序序列 for(int i=0;i<4;i++){for(int j=0;j<13;j++){cards[n]=cardsByBin[i][j];n++;} }
}void main(){printf("排序 按照花色从小到大 数值从小到大 \n");Card cards[52] ; printf("洗牌ing.....\n");shuffleCards(cards); //洗牌 printf("排序前的牌\n");printCards(cards); //打印扑克牌 printf("排序ing.....\n");
// sortCardsWithLSD(cards);//排序
// sortCardsWithMSD(cards);//排序 sortCardsWithBinSort(cards);printf("排序后的牌\n");printCards(cards); //打印扑克牌 }
9.6.2 链式基数排序
11-链式基数排序.c
#include <stdio.h>
#include <stdlib.h>
#include "0-RecordList.h"typedef RecordType DataType;
#include "链队列.c"int digit(KeyType key, int m, int r);//【算法9-16】基于链队列的基数排序
void RadixSort(RecordType L[] ,int n,int m,int r){//L中的关键字为m为r进制数,L的长度为nLQueue** Queue;int i,j,k;Queue=(LQueue**)malloc(r*sizeof(LQueue*));for(i=0;i<r;i++){ //初始化r个链队列Queue[i]=Init_LQueue();}for (i = 0; i<m ; i++) { //进行m次分配与收集for (j=0;j<=n;j++){ //分配k=digit(L[j].key,i,r); //提取当前关键字中第m位的数字值InLQueue(Queue[k],L[j]);}k=0;for (j = 0; j < r; j++) { //收集for ( ; !Empty_LQueue(Queue[j]); k++) {Out_LQueue(Queue[j],&(L[k]));}}}}
//【算法9-17】提取关键字中第m位的数字值
int digit(KeyType key, int m, int r){int i,d;if(m==0){return key %r;}d=r;for (i = 1; i<m ; i++) {d*=r;}return ((int)(key/d)%r);
}
int main(){int n=9;int nums[10]={-1,921,435,628,285,862,225,448,193,430};//0号不存储元素 RecordList L=create(nums,n);print(L);//921 435 628 285 862 225 448 193 430RadixSort(L.r,9,3,10); print(L);//193 225 285 430 435 448 628 862 921
}
9.7 外部排序
9.7.1置换选择排序
9.7.2多路归并外排序
9.8 算法总结
最后
2023-11-7 19:26:28
我们都有光明的未来
不必感谢我,也不必记得我
祝大家考研上岸
祝大家工作顺利
祝大家得偿所愿
祝大家如愿以偿
点赞收藏关注哦
相关文章:

第九章 排序【数据结构】【精致版】
第九章 排序【数据结构】【精致版】 前言版权第九章 排序9.1 概述9.2 插入类排序9.2.1 直接插入排序**1-直接插入排序.c** 9.2.2 折半插入排序**2-折半插入排序.c** 9.2.3 希尔排序 9.3 交换类排序9.3.1冒泡排序**4-冒泡排序.c** 9.3.2 快速排序**5-快速排序.c** 9.4 选择类排…...

基于element-plus定义表格行内编辑配置化
文章目录 前言一、新增table组件二、使用步骤 前言 在 基于element-plus定义表单配置化 基础上,封装个Element-plus的table表格 由于表格不同于form组件,需自定义校验器,以下组件配置了单个校验,及提交统一校验方法,且…...

WebGL-Vue3-TS-Threejs:基础练习 / Javascript 3D library / demo
一、理解Three.js Three.js是一个用于WebGL渲染的JavaScript库。它提供了一组工具和类,用于创建和渲染3D图形和动画。简单理解(并不十分准确),Three.js之于WebGL,好比,jQuery.js之于JavaScript。 OpenGL …...

2022年12月 Python(四级)真题解析#中国电子学会#全国青少年软件编程等级考试
Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 有n个按名称排序的商品,使用对分查找法搜索任何一商品,最多查找次数为5次,则n的值可能为?()(2分) A.5 B.15 C.30 D.35 答案:C 答案解析:对分查找最多查找次数m与个数之间n的…...

确定性 vs 非确定性:GPT 时代的新编程范式
分享嘉宾 | 王咏刚 责编 | 梦依丹 出品 | 《新程序员》编辑部 在 ChatGPT 所引爆的新一轮编程革命中,自然语言取代编程语言,在只需编写提示词/拍照就能出程序的时代,未来程序员真的会被简化为提示词的编写员吗?通过提示词操纵 …...

【Linux奇遇记】我和Linux的初次相遇
🌈个人主页: Aileen_0v0 🔥系列专栏:Linux奇遇记系列专栏💫"没有罗马,那就自己创造罗马~" 目录 前端和后端的介绍 1.前端 2.后端 3.前后端区别 Linux在前后端开发中的角色 如何学习Linux 去进行程序开发 Linux的常见根目…...

剪贴板劫持--PasteJacker的使用
启动 PasteJacker [1] Windows [2] Linux [3] Exit第一次是让我们选择要攻击针对的目标系统,这里以Windows系统为例,即我自己的物理机 因此键入 1 ,回车 [1] Download and execute a msfvenom backdoor using certutil (Web delivery Past…...
说一下vue2的响应式原理?
vue2采用数据代理数据劫持发布订阅模式的方法。 在初始化vue实例时,会把data对象和data对象的属性都添加到vm对象中,通过object.defineProperty()进行数据代理,用vm对象的属性来代理data对象的属性,并在Observer类中递归遍历data…...

如何使用CORS和CSP保护前端应用程序安全
前端应用在提供无缝用户体验方面起着核心作用。在当今互联网的环境中,第三方集成和API的普及使得确保强大的安全性至关重要。安全漏洞可能导致数据盗窃、未经授权访问以及品牌声誉受损。本文将向您展示如何使用CORS和CSP为您的网页增加安全性。 嗨,大家好…...

C/C++输出硬币翻转 2021年6月电子学会青少年软件编程(C/C++)等级考试一级真题答案解析
目录 C/C硬币翻转 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 C/C硬币翻转 2021年6月 C/C编程等级考试一级编程题 一、题目要求 1、编程实现 假设有N个硬币(N为不大于5000的正整数),从1…...
ipad可能会在iOS 16中失去智能家居中心功能
在iOS 16测试版代码中发现的文本表明苹果将放弃对iPad家庭中心的支持 家庭app迎来重大改版,未来更将对智能家居互联互通标准Matter提供支持。 即使某一款智能家居设备再优秀,只要它没有接入HomeKit,那么就不能在苹果的家庭app中直接管理控制。…...
maven打包可运行jar
普通java程序 <build><finalName>JavaDeviceClient</finalName><plugins><plugin><artifactId>maven-compiler-plugin</artifactId><version>2.3.2</version><configuration><source>1.8</source><…...

Arcgis连接Postgis数据库(Postgre入门十)
效果 步骤 1、矢量数据首先有在postgis数据库中 这个postgis数据库中的一个空间数据,数据库名称是test3,数据表名称是test 2、Arcgis中连接postgis数据库中 3、成功连接 可以将数据拷贝或导入到gdb数据库中...

【蓝桥杯选拔赛真题17】C++时间换算 第十二届蓝桥杯青少年创意编程大赛C++编程选拔赛真题解析
目录 C/C++时间换算 一、题目要求 1、编程实现 2、输入输出 二、算法分析 <...

【腾讯云 HAI域探秘】探索AI绘画之路:利用腾讯云HAI服务打造智能画家
目录 前言1 使用HAI服务作画的步骤1.1 注册腾讯云账户1.2 创建算力服务器1.3 进入模型管理界面1.4 汉化界面1.5 探索AI绘画 2 模型参数的含义和调整建议2.1 模型参数的含义和示例2.2 模型参数的调整建议 3 调整参数作画的实践和效果3.1 实践说明3.2 实践效果13.3 实践效果23.4 …...
安卓常见设计模式10------责任链模式(Kotlin版)
1. W1 是什么,什么是责任链模式? 责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,它用于将请求的发送者和接收者解耦,并将请求沿着一个处理链进行传递,直到有一个处理者能…...
利用 Google Artifact Repository 构建maven jar 存储仓库
参考了google 官方文档 https://cloud.google.com/artifact-registry/docs/java/store-java#gcloud_1 首先 enable GAR api gcloud services enable artifactregistry.googleapis.com gcloud services list | grep -i artifact artifactregistry.googleapis.com Artifac…...

Facebook广告被暂停是什么原因?Facebook广告账号被封怎么办?
许多做海外广告投放的小伙伴经常遇到一个难题,那就是投放的Facebook广告被拒或 Facebook 广告帐户被关闭赞停的经历,随之而来的更可能是广告账户被封,导致资金的损失。本文将从我自身经验,为大家分享,Facebook广告被暂…...

Javaweb之javascript的BOM对象的详细解析
1.5.2 BOM对象 接下来我们学习BOM对象,BOM的全称是Browser Object Model,翻译过来是浏览器对象模型。也就是JavaScript将浏览器的各个组成部分封装成了对象。我们要操作浏览器的部分功能,可以通过操作BOM对象的相关属性或者函数来完成。例如:…...

使用Nginx和Spring Gateway为SkyWalking的增加登录认证功能
文章目录 1、使用Nginx增加认证。2、使用Spring Gateway增加认证 SkyWalking的可视化后台是没有用户认证功能的,默认下所有知道地址的用户都能访问,官网是建议通过网关增加认证。 本文介绍通过Nginx和Spring Gateway两种方式 1、使用Nginx增加认证。 生…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
FastAPI 教程:从入门到实践
FastAPI 是一个现代、快速(高性能)的 Web 框架,用于构建 API,支持 Python 3.6。它基于标准 Python 类型提示,易于学习且功能强大。以下是一个完整的 FastAPI 入门教程,涵盖从环境搭建到创建并运行一个简单的…...
MVC 数据库
MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

wpf在image控件上快速显示内存图像
wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...