除vector之外的容器:
1.list:双向动态链表(循环双链表)
单链表,前一节点的next指针指向下一个节点。
双链表:每一个节点有两个指针,一个指针指向下一个节点,另一个指针指向前一个节点。
循环双链表:最后一个节点next指针指向第一个节点,第一个节点的pret指针指向最后一个节点。自学如何使用
有了数组之后,为什么还要有链表?数组和链表各有什么优势与劣势。
数组和链表的区别:(背了没用,一定要理解,将来以后在写项目的时候一定要能在众多的数据结构中找到最适合这个项目的数据结构以及算法,所以我们要知道每一种数据结构的特性是什么,每一种容器要自己能实现它,只有自己写才能知道优势在什么地方)
- 链表插入删除效率高
- 数组连续,链表不连续
- 因为数组连续,所以数组查找效率高
2.deque:双向的动态队列
介于数组和链表之间,它的查找效率要高于链表,低于数组。它的插入删除效率要高于数组,低于链表。
将队列坎成几段,段与段之间如同双向链表一样连起来。
自学如何使用。
高级排序算法:
1.shell排序(优化后的插入排序)
比较快的一种排序算法。
步长:步长一开始设置为元素个数/2。首次步长 次排序,每次排序都以步长为间隔给所有元素分组(步长为多少,就能分成多少组),(这样就能减少插入排序时,往后挪的元素的个数)组内做插入排序,排序完,步长减1,开始下一次排序。
#include <iostream>
#define NUM 10
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
/*void insert_sort(int* a,int len){//插入排序
//定义变量保存待插元素
int temp;
int j;
//找到待插元素(a[i})
for(int i=1;i<len;i++){
temp=a[i];//temp保存待插元素
j=i-1;
//3待插元素之前数据后移
while(j>=0&&a[j]>temp)
{
a[j+1]=a[j]; //数据后移
j--;
}
a[j+1]=temp;//4待插元素赋值给a[j+1]
}
*/
void shell_sort(int*a,int len){
//1计算最初步长
int step=len/2;
//2 按照步长来做插入排序 每次步长减1.
while(step){//step=step>>1
//3 分组做插入排序
int temp;
int j;
for(int i=step;i<len;i=i+step) {
temp=a[i];//temp保存待插元素
j=i-step;
//3待插元素之前数据后移
while(j>=0&&a[j]>temp)
{
a[j+step]=a[j]; //数据后移
j=j-step;
}
a[j+step]=temp;//4待插元素赋值给a[j+1]
}
step--;
}
}
void print(int* a,int len){
for(int i=0;i<len;i++){
cout<<a[i]<<" ";
}
cout<<endl;
}
int main(int argc, char** argv) {
int a[NUM]={9,66,54,33,-5,78,123,0,8,7};
cout<<"before sort:";
print(a,10);
shell_sort(a,10);
cout<<"after sort:";
print(a,10);
return 0;
}
2.基数排序:数组下标天然有序
限制:
1.不能重复
2.空间浪费大
#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
void radix_sort(int*a,int len,int max){
//1创建临时数组,数组大小取决于待排元素中最大元素的值。
int*b =new int[max+1];
// 2初始化临时数组
for(int i=0;i<=max;i++){
b[i]=-1;
}
//3 排序
for(int i=0;i<len;i++){
b[a[i]]=a[i];
}
for(int i=0;i<=max;i++){
if(b[i]!=-1) cout<<b[i]<<" ";
}
}
int main(int argc, char** argv) {
int a[10]={9,6,5,7,4,8,0,1,6,8};//限制数组中元素不能为负;
radix_sort(a,10,9);
return 0;
}
3.桶排序:
思路:待排数组有多少元素,搞多少个桶;先按照个位大小排序即个位相同放在一个桶里,个位不同按照个位基数排序。然后按照十位排序,然后按照百位排序。。。
#include <iostream>
#include <string.h>
#define AREA 999;
#define NUM 10
void bucket_sort(int*a,int len);
using namespace std;
void print(int* a,int len){
for(int i=0;i<len;i++){
cout<<a[i]<<" ";
}
cout<<endl;
}
int main(){
int a[10]={33,356,789,4,11,45,77,88,909,111};
cout<<"before sort:";
print(a,10);
bucket_sort(a,10);
cout<<"afte sort:";
print(a,10);
return 0;
}
void bucket_sort(int*a,int len){
//1.根据数据范围获取排序次数
for(int i=1;i<999;i*=10 ){
//2 做桶并初始化
int temp[10][NUM];//桶的个数是10,每个桶的容量是NUM。待排数组中有多少个元素就设置多少个桶,因为有一种可能就是待排数组元素个位(十位,百位)全部不同。
memset(temp,-1,sizeof(int)*10*NUM);
//3遍历a数组 并按照排序依据把a数组元素存放到temp中
for(int j=0;j<len;j++){
int m=a[j]/i%10;//i=1时得到个位,i=10时得到十位,i=100时得到百位。
temp[m][j]=a[j];//把a中元素放到合适的桶的合适位置上。
}
//4放回原来数组
int k=0;
for(int i=0;i<10;i++){
for(int j=0;j<NUM;j++){
if(temp[i][j]!=-1){
a[k++]=temp[i][j];
}
}
}
}
}
总结:
shell排序速度快,不稳定。桶排序:速度快,稳定,空间复杂度高 利用空间算时间。