数据结构学习第二十三天

13:50:24 2019-09-14

继续把未看完的看完

排序算法

定理:任意$N$个不同元素组成的序列平均具有$N(N-1)/4$个逆序对

定理:任何仅以交换相邻两元素来排序的算法,其平均时间复杂度为$Ω(N^2)$

这样子 冒泡排序 插入排序 的最坏情况都是 N^2

要使排序算法变高效 得使用间隔元素来交换 在一次排序中 交换多个逆序对的元素

希尔排序

定义增量序列$D_M>D_{M-1}>...>D_1=1$

$对每个D_k进行“D_k-间隔”排序(k=M,M-1,...1)$

$注意:“D_k-间隔"有序的序列,在执行”D_{k-1}间隔“排序后,仍然是“D_k-间隔"有序的$

如果增量元素不互质,则小增量可能根本不起作用

比如 $N=N/2$ 最坏情况 时候 $T=\theta(N^{2})$

那么就会有其他的增量序列:

  Hibbard增量序列 $D_k=2^k-1$  --相邻元素互质  最坏情况$T=\theta(N^{3/2})$

  猜想 Hibbard增量的 平均复杂度 $T_{avg}=O(N^{5/4})$

  Sedgewick增量序列 $ \{1,5,19,41,109,.....\}$

  $9*4^i-9*2^i或4^i-3*2^i+1$猜想$T_{avg}=O(N^{7/6})  T_{worst}=O(N^{4/3})$

冒泡排序 插入排序 希尔排序 选择排序 堆排序 归并排序(ps:其中堆排序写的是憨憨版本 之后会添上精明版本)

  1 #define _CRT_SECURE_NO_WARNINGS
  2 #include<stdio.h>
  3 #include<malloc.h>
  4 void Print(int A[], int N)
  5 {
  6     for (int i = 0; i < N; i++)
  7         printf("%d ", A[i]);
  8     printf("\n");
  9 }
 10 //排序算法
 11
 12 //冒泡排序   //最好 O(N) 最坏 O(N^2)  算法稳定
 13 void Swap(int A[], int i, int j)
 14 {
 15     int temp = A[i];
 16     A[i] = A[j];
 17     A[j] = temp;
 18 }
 19 void Bubble_Sort(int A[], int N)
 20 {
 21     for (int i = 0; i < N; i++)
 22     {
 23         int IsSwap = 0;
 24         for (int j = 0; j < N - i-1; j++)
 25         {
 26             if (A[j] > A[j + 1])
 27             {
 28                 IsSwap = 1;
 29                 Swap(A, j, j + 1);
 30             }
 31         }
 32         if (!IsSwap)
 33             break;
 34     }
 35 }
 36
 37 //插入排序  //最好O(N) 最坏 O(N^2)  算法稳定
 38 void Insert(int A[], int j, int i)
 39 {
 40     int temp = A[i];
 41     for (; i > j; i--)
 42         A[i] = A[i - 1];
 43     A[j] = temp;
 44 }
 45 void Insert_Sort(int A[], int N)
 46 {
 47     /*for (int i = 0; i < N-1; i++)
 48     {
 49         int m = i + 1;
 50         int j = i;
 51         while (j >= 0 && A[j] > A[m])
 52             j--;
 53         Insert(A, j+1, m);
 54     }*/
 55     /*for (int i = 1; i < N; i++)
 56     {
 57         int temp = A[i];
 58         int j;
 59         for (j = i - 1; j >= 0 && A[j] > temp; j--)
 60             A[j + 1] = A[j];
 61         A[j + 1] = temp;
 62     }*/
 63     for (int p = 1; p < N; p++)
 64     {
 65         int temp = A[p];
 66         int i;
 67         for (i = p; i > 0 && A[i - 1] > temp; i--)
 68             A[i] = A[i - 1];
 69         A[i] = temp;
 70     }
 71 }
 72
 73 //希尔排序  //最坏情况  //改进插入排序
 74 void Shell_Sort(int A[], int N)
 75 {
 76     /*for (int D = N / 2; D > 0; D /= 2)
 77     {
 78         for (int p = D; p < N; p++)
 79         {
 80             int temp = A[p];
 81             int i;
 82             for (i = p; i >= D && A[i - D] > temp; i -= D)
 83                 A[i] = A[i - D];
 84             A[i] = temp;
 85         }
 86     }*/
 87     // 利用Sedgewick增量序列
 88     int Si;
 89     int Sedgewick[] = { 929,505,209,109,41,19,5,1,0 };
 90     for (Si = 0; Sedgewick[Si] >=N; Si++)  //初始的增量Sedgewick[Si]不能超过待排序序列长度
 91         ;
 92     for (int D = Sedgewick[Si]; D>0;D=Sedgewick[++Si])
 93     {
 94         for (int p = D; p < N; p++)
 95         {
 96             int temp = A[p];
 97             int i;
 98             for (i = p; i >= D && A[i - D] > temp; i -= D)
 99                 A[i] = A[i - D];
100             A[i] = temp;
101         }
102     }
103 }
104
105 //选择排序
106 void Selection_Sort(int A[], int N)
107 {
108     for (int i = 0; i < N; i++)
109     {
110         int MinPosition = i;
111         int Min = A[i];
112         int j;
113         for (j = i + 1; j < N; j++)
114         {
115             if (A[j] < Min)
116             {
117                 MinPosition = j;
118                 Min = A[j];
119             }
120         }
121         Swap(A, i, MinPosition);
122     }
123 }
124
125 //堆排序  //选择排序的一种改进
126 //改进了寻找最小元的算法 利用最小堆来实现
127 typedef struct HeapStruct* MinHeap;
128 struct HeapStruct
129 {
130     int* Elements;
131     int Size;
132     int Capacity;
133 };
134 MinHeap Create(int MaxSize)
135 {
136     MinHeap H = (MinHeap)malloc(sizeof(struct HeapStruct));
137     H->Elements = (int*)malloc(sizeof(int) * (MaxSize + 1));
138     H->Capacity = MaxSize;
139     H->Size = 0;
140     H->Elements[0] = -10001;
141     return H;
142 }
143 MinHeap H = Create(20);
144 //建立最小堆
145 void PrecDown(MinHeap H, int i)  //下滤
146 {
147     int Parent, Child;
148     int Tmp = H->Elements[i];
149     for (Parent = i; Parent * 2 <= H->Size; Parent = Child)
150     {
151         Child = Parent * 2;
152         if ((Child != H->Size) && (H->Elements[Child] > H->Elements[Child + 1]))
153             Child++;
154         if (Tmp <= H->Elements[Child])break;
155         else
156             H->Elements[Parent] = H->Elements[Child];
157     }
158     H->Elements[Parent] = Tmp;
159 }
160 void BuildMinHeap(MinHeap H)
161 {
162     int i;
163     for (i = H->Size / 2; i > 0; i--)
164         PrecDown(H, i);
165 }
166 int DeleteMin(MinHeap H)
167 {
168     int Parent, Child;
169     int MinItem, temp;
170     MinItem = H->Elements[1];
171     temp = H->Elements[H->Size--];
172     for (Parent = 1; Parent * 2 <= H->Size; Parent = Child)
173     {
174         Child = Parent * 2;
175         if (Child != H->Size && H->Elements[Child] > H->Elements[Child + 1])
176             Child++;
177         if (H->Elements[Child] >= temp)break;
178         else
179             H->Elements[Parent] = H->Elements[Child];
180     }
181     H->Elements[Parent] = temp;
182     return MinItem;
183 }
184 void Heap_Sort(int A[], int N)
185 {
186     //算法一 利用最小堆
187     /*int Tmp[10] = { 0 };
188     for (int i = 0; i < 10; i++)
189         Tmp[i] = DeleteMin(H);
190     for (int i = 0; i < 10; i++)
191         A[i] = Tmp[i];*/
192     /*for (int i = 0; i < 10; i++)
193         A[i] = DeleteMin(H);*/
194
195     //算法二 利用最大堆后 再调整
196 }
197
198 //归并排序
199 void Merge(int A[],int lo,int mi,int hi)
200 {
201     //两个有序序列的合并
202     int* B = (int*)malloc(sizeof(int) * (mi - lo));
203     for (int i = 0; i < mi - lo;)B[i++] = A[lo + i];
204     int i, j, k;
205     i = lo;
206     j = 0;
207     k = mi;
208     /*while (j<mi-lo||k<hi)
209     {
210         if((j<mi-lo)&&(k>=hi||B[j]<=A[k]))A[i++]=B[j++];
211         if ((k < hi) && (j >= mi-lo|| B[j] > A[k]))A[i++] = A[k++];
212     }*/
213     //化简版
214     while (j<mi-lo)
215     {
216         if (k >= hi || B[j] <= A[k])A[i++] = B[j++];
217         if (k<hi && B[j]>A[k])A[i++] = A[k++];
218     }
219     /*邓公版本*/
220     /*int* A1= A + lo;
221     int* B = (int*)malloc(sizeof(int) * (mi - lo));
222     for (int i = 0; i < mi - lo; B[i] = A1[i++]);
223     int* C = A + mi;
224     int i, j, k;*/
225     /*for (i = j = k = 0; j < mi - lo || k < hi-mi;)
226     {
227         if (j < mi - lo&&((k >= hi - mi)||B[j] <=C[k]))A1[i++] = B[j++];
228         if (k < hi - mi && (j >= mi - lo || B[j] > C[k]))A1[i++] = C[k++];
229     }*/
230     //简化
231     /*for (i = j = k = 0; j < mi - lo;)
232     {
233         if (k >= hi - mi || B[j] <= C[k])A1[i++] = B[j++];
234         if (k < hi - mi && (j >= mi - lo || B[j] > C[k]))A1[i++] = C[k++];
235     }*/
236 }
237 void MergeSort(int A[],int lo,int hi)
238 {
239     if (lo == hi - 1)
240         return;
241     int mi = (lo + hi) >> 1;
242     MergeSort(A,lo, mi);
243     MergeSort(A, mi, hi);
244     Merge(A,lo, mi, hi);
245 }
246 int main()
247 {
248     int A[10];
249     for (int i = 0; i < 10; i++)
250         scanf("%d", &A[i]);
251     //Bubble_Sort(A, 10);
252     //Insert_Sort(A, 10);
253     //Shell_Sort(A, 10);
254     //Selection_Sort(A, 10);
255     //堆排序
256     /*for (int i = 1; i <= 10; i++)
257         H->Elements[++H->Size] = A[i - 1];
258     BuildMinHeap(H);   //构建最小堆
259     Heap_Sort(A, 10);*/
260     MergeSort(A,0,10);
261     Print(A, 10);
262     return 0;
263 }

原文地址:https://www.cnblogs.com/57one/p/11519108.html

时间: 2024-10-20 05:27:14

数据结构学习第二十三天的相关文章

穿上华丽的外衣——CSS之旅(码神学习第二十三天)

穿上华丽的外衣--CSS之旅 码神学习第二十三天 学习过程记录: 1.CSS(Cascading Style Sheets,层叠样式表),为了解决内容与表现分离.样式通常存储在样式表中.外部样式表可以提高工作效率. 2.三种不同类型的CSS样式: 答:①内联样式:直接在html标签上定义该标签的CSS样式 ②内部样式:写在html文件中,且包含在<style></style>代码块中 ③外部样式:通过在html中引用外部css文件来控制样式 元素的优先级,就近原则,离元素最近的规则

Python 学习第二十三天 django 知识(五)

一,django 的model操作 1,字段 AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - bigint自增列,必须填入参数 primary_key=True 注:当model中如果没有自增列,则自动会创建一个列名为id的列 from django.db import models class UserInfo(models.Model): # 自动创建一个列名为id的且为自增的整数列 us

JAVA学习第二十三课(多线程(二))- (多线程的创建方式二 :实现Runnable接口(常用))

当一个类有父亲,但是其中的功能还希望实现线程,那么就不能采用继承Thread的方式创建线程 那么就可以通过接口的方式完成 准备扩展Demo类的功能,让其中的内容可以作为线程的任务执行 实现Runnable接口,Runnable接口中只有一个方法run 一.创建线程的第二种方法 Runnable的出现仅仅是将线程的任务进行了对象的封装 /* * 创建线程的第二种方法 * 1.定义类实现Runnable接口 * 2.覆盖接口中的fun方法,将线程的任务代码封装到run方法中 * 3.通过Thread

Java进阶学习第二十三天——国际化与AJAX、JSON

文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 2016.06.10 lutianfei none 国际化 软件的国际化:软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的.符合来访者阅读习惯的页面或数据. 国际化又称为 i18n:internationalization 软件实现国际化,需具备哪些特征: 对于程序中固定使用的文本元素,例如菜单栏.导航条等中使用的文本元素.或错误提示信息,状态信息等,需要根据来访者的地区和国家,选择不

linux基础学习第二十三天linux安全和加密之SSL\TLS协议、CA、openssl

内容: 1.通信加密类型及算法 2.TLS/SSL协议的引入及其通信过程 3.CA.数字签名的引入 4.一个安全的数据通信交换过程 5.openssl工具的使用 6.自制私有根CA过程 一.通信加密类型及算法 数据加密通信的重要性不言而喻,美国NIST,为了保证计算机的安全,提出了几个要求: (1).数据要有保密性:数据保密性和隐私性:确保信息不被别人获取,个人存储的信息不能被别人收集到: (2).完整性:包括数据完整性和系统完整性:数据完整性确保数据和程序只能以特定权限的进行授权和改变,只能授

No_16_0324 Java基础学习第二十三天

文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 2016.03.24 lutianfei none 登录注册IO版 如下代码仅为UserDaoImpl类文件,其他原码参考day22_login_regist工程 public class UserDaoImpl implements UserDao { // 为了保证文件一加载就创建 private static File file = new File("user.txt"); static { try { fil

linux基础学习第二十三天之openssh、sudo

内容: 1.openssh的介绍和使用 (1)sshd的服务端配置 (2)基于密钥登陆ssh的使用 (3)scp的使用 (4)rsync的使用 2.sudo的介绍和配置使用 一.openssh OpenSSH与SSH协议是远程登录的首选连接工具.它加密所有流量,以消除窃听,连接劫持和其它攻击. OpenSSH的套件包括以下工具: 远程操作使用 SSH, SCP,和 SFTP. 密钥管理 ssh-add, ssh-keysign, ssh-keyscan和ssh-keygen 服务端组成 sshd

YII学习第二十三天,accessRules用法

访问控制过滤器(Access Control Filter)访问控制过滤器是检查当前用户是否能执行访问的controller action的初步授权模式. 这种授权模式基于用户名,客户IP地址和访问类型. 访问控制过滤器,适用于简单的验证. 需要复杂的访问控制,需要使用将要讲解到的基于角色访问控制(role-based access (RBAC)). 在控制器(controller)里重载CController::filters方法,设置访问过滤器来控制访问动作(看 Filter 了解更多过滤器

20172322 2017-2018-2 《程序设计与数据结构》第二周学习总结

20172322 2017-2018-2 <程序设计与数据结构>第二周学习总结 教材学习内容总结 了解了print与println的区别 了解了字符串的拼接可以用+来完成 了解了转义字符的使用 学会了使用赋值 学会使用部分算术运算符 学会了使用Scanner来实现交互性 教材学习中的问题和解决过程 问题1:在最初接触赋值时对foalt和double的赋值范围不了解 问题1解决方案:使用万能的度娘后看到一个高赞答案后有了了解 问题2:在提前预习时看到2.7图形后敲入的代码无法执行 问题2解决方案