c程序设计语言笔记3
来源:互联网 发布:美化你的声音 知乎 编辑:程序博客网 时间:2024/05/18 01:59
折半查找法:
#include <stdio.h>#include <stdlib.h>//折半查找函数int binsearch();main(){int x,s[10] = {1,2,3,4,5,6,7,8,9,10};printf("Please input the number you want to find.\n");x = getchar() - '0';printf("x = s[%d]\n",binsearch(x,s,10));system("pause");}int binsearch(int x,int v[],int n){int low,high,mid;low = 0;high = n - 1;while(low <= high){mid = (low + high) / 2;if(x < v[mid])high = mid - 1;else if(x > v[mid])low = mid + 1;else return mid;}return -1;}
希尔排序(Shell Sort)是插入排序的一种。是针对直接插入排序算法的改进。该方法又称缩小增量排序,
希尔排序基本思想:
先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2<d1重复上述的分组和排序,直至所取的增量dt=1(dt<dt-l<…<d2<d1),即所有记录放在同一组中进行直接插入排序为止。
#include <stdio.h>#include <stdlib.h>//shell排序法void shellsort();main(){int i, v[10] = {10,5,2,4,6,8,9,1,3,7};for(i = 0;i < 10;i++)printf("%d ",v[i]);printf("\n");shellsort(v,10);for(i = 0;i < 10;i++)printf("%d ",v[i]);system("pause");}//shellsort函数:按递增顺序对v[0]--v[n-1]排序void shellsort(int v[],int n){int gap,i,j,temp;for(gap = n / 2;gap > 0;gap /= 2)for(i = gap;i < n;i++)for(j = i - gap;j >= 0 && v[j] > v[j + gap];j -= gap){temp = v[j];v[j] = v[j + gap];v[j + gap] = temp;}}
插入排序算法思路:
假定这个数组的序是排好的,然后从头往后,如果有数比当前外层元素的值大,则将这个数的位置往后挪,直到当前外层元素的值大于或等于它前面的位置为止.这具算法在排完前k个数之后,可以保证a[1…k]是局部有序的,保证了插入过程的正确性.
算法描述:
一般来说,插入排序都采用in-place在数组上实现。具体算法描述如下:
1. 从第一个元素开始,该元素可以认为已经被排序
2. 取出下一个元素,在已经排序的元素序列中从后向前扫描
3. 如果该元素(已排序)大于新元素,将该元素移到下一位置
4. 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
5. 将新元素插入到该位置中
6. 重复步骤2
(如果比较操作的代价比交换操作大的话,可以采用二分查找法来减少比较操作的数目。该算法可以认为是插入排序的一个变种,称为二分查找排序。)
- void insertSort(char array[], int n)
- {
- int i,j;
- int temp;
- for(i=0;i<n;i++)
- {
- temp=array[i];
- for(j=i; j>0 && temp<array[j-1];j--)
- array[j]=array[j-1];
- array[j]=temp;
- }
- }
#include <stdio.h>#include <stdlib.h>//wϰ3-3void expand();main(){char s1[10] = "a-gddx-z";char s2[100];expand(s1,s2);printf("%s\n%s",s1,s2);system("pause");}//expand :expand shorthand notation in s1 into string s2void expand(char s1[],char s2[]){char c;int i,j;i = j =0;while((c = s1[i++]) != '\0')if(s1[i] == '-' && s1[i + 1] >= c){i++;while(c < s1[i])s2[j++] = c++;}else s2[j++] = c;s2[j] = '\0';}
练习3-4,(这是一个纠结的问题)在数的对二的补码表示中,我们编写的itoa函数不能处理最大的负数,即n等于-2^(字长-1)的情况。请解释其原因。修改函数,使它能在任何机器上运行时都能打印出正确的值。
#include <stdio.h>#include <string.h>//itoa 处理最大的负数#define abs(x) ((x) < 0 ? -(x) : (x))#define MAXCHAR 100void reverse (char s[]);void itoa (int n,char s[]);main(){int i = -2147483648,j;char s[MAXCHAR]; for (j = 0;j < MAXCHAR;j++) { s[j]=0; }itoa(i,s);printf("%s\n",s);getch();}void reverse(char s[]){int i,j,c;for(i = 0,j = strlen(s) - 1;i < j;i++,j--){c = s[i];s[i] = s[j];s[j] = c;}}void itoa(int n,char s[]){int sign,i;sign = n;i = 0;do{s[i++] = abs(n) % 10 + '0';}while((n /= 10) != 0);if(sign < 0)s[i++] = '-';s[i] = '\0';reverse(s);}
另一种版本:
#include <stdio.h>#include <string.h>//itoa 处理最大的负数#define abs(x) ((x) < 0 ? -(x) : (x))#define MAXCHAR 100void reverse (char s[]);void itoa (int n,char s[]);main(){int i = -2147483648,j;char s[MAXCHAR]; for (j = 0;j < MAXCHAR;j++) { s[j]=0; }itoa(i,s);printf("%s\n",s);getch();}void reverse(char s[]){int i,j,c;for(i = 0,j = strlen(s) - 1;i < j;i++,j--){c = s[i];s[i] = s[j];s[j] = c;}}void itoa(int n,char s[]){int sign,i;sign = n;i = 0;do{s[i++] = abs(n) % 10 + '0';}while((n /= 10) != 0);if(sign < 0)s[i++] = '-';s[i] = '\0';reverse(s);}
Exercise 3-4 explanation: There are a number of ways of representing signed integers in binary, for example, signed-magnitude, excess-M, one's complement and two's complement. We shall restrict our discussion to the latter two. In a one's complement number representation, the binary represenation of a negative number is simply the binary representation of its positive counterpart, with the sign of all the bits switched. For instance, with 8 bit variables:
SIGNED BINARY UNSIGNED 25 00011001 25 -25 11100110 230 127 01111111 127 -127 10000000 128
The implications of this are (amongst others) that there are two ways of representing zero (all zero bits, and all one bits), that the maximum range for a signed 8-bit number is -127 to 127, and that negative numbers are biased by (2^n - 1) (i.e. -I is represented by (2^n - 1) - (+I). In our example, so:
Bias = 2^8 - 1 = 255 = 11111111 Subtract 25 = 00011001 Equals = 11100110
In a two's complement representation, negative numbers are biased by 2^n, e.g.:
Bias = 2^8 = 100000000 Subtract 25 = 00011001 Equals = 11100111
In other words, to find the two's complement representation of a negative number, find the one's complement of it, and add one. The important thing to notice is that the range of an 8 bit variable using a two's complement representation is -128 to 127, as opposed to -127 to 127 using one's complement. Thus, the absolute value of the largest negative number cannot be represented (i.e. we cannot represent +128). Since the itoa() function in Chapter 3 handles negative numbers by reversing the sign of the number before processing, then adding a '-' to the string, passing the largest negative number will result it in being translated to itself:
-128 : 10000000 One's complement: 01111111 Subtract 1 : 10000000
Therefore, because (n /= 10) will be negative, the do-while loop will run once only, and will place in the string a '-', followed by a single character, (INT_MIN % 10 + '0'). We can remedy these two bugs in the following way: 1 - change 'while ((n /= 10) > 0)' to 'while (n /= 10)'. Since any fractional part is truncated with integer division, n will eventually equal zero after successive divides by 10, and 'n /= 10' will evaluate to false sooner or later. 2 - change 'n % 10 + '0'' to 'abs(n % 10) + '0'', to get the correct character. EX3_4.C shows the revised function, which will run correctly regardless of the number representation.
/* EX3_4.C ======= Suggested solution to Exercise 3-4 */ #include <stdlib.h>#include <stdio.h>#include <limits.h>void itoa(int n, char s[]);void reverse(char s[]);int main(void) { char buffer[20]; printf("INT_MIN: %d\n", INT_MIN); itoa(INT_MIN, buffer); printf("Buffer : %s\n", buffer); return 0;}void itoa(int n, char s[]) { int i, sign; sign = n; i = 0; do { s[i++] = abs(n % 10) + '0'; } while ( n /= 10 ); if (sign < 0) s[i++] = '-'; s[i] = '\0'; reverse(s);}void reverse(char s[]) { int c, i, j; for ( i = 0, j = strlen(s)-1; i < j; i++, j--) { c = s[i]; s[i] = s[j]; s[j] = c; }}
练习3-5 编写函数itob(n,s,b),将整数n转换为以b为底的数,并将转换的结果以字符形式保存到字符串s中。
#include <stdio.h>#include <string.h>//ex3.5void reverse(char s[]);void itob(int n,char s[],int b);main(){int n,b;char s[100];printf("Please input your number:\n");scanf("%d", &n);printf("Please input your base number:\n");scanf("%d,%d,%d", &b);itob(n,s,b);printf("\nThe string is %s",s);getch();}void itob(int n,char s[],int b){int i,j,sign;if((sign = n) < 0)n = -n;i = 0;do{j = n % b;s[i++] = (j <= 9) ? j + '0':j + 'a' - 10;}while((n /= b) > 0);if (sign < 0)s[i++] = '-';s[i] = '\0';reverse(s);}void reverse(char s[]){int i,j,c;for(i = 0,j = strlen(s) - 1;i < j;i++,j--){c = s[i];s[i] = s[j];s[j] = c;}}
- c程序设计语言笔记3
- C程序设计语言学习笔记(3)
- C程序设计语言学习笔记
- c程序设计语言笔记1
- c程序设计语言笔记2
- c程序设计语言笔记4
- C程序设计语言笔记1
- c程序设计语言学习笔记
- C程序设计语言笔记
- 【C程序设计语言】第一章 - 笔记
- C程序设计语言 笔记
- 《C程序设计语言》笔记----第一章 导言
- C程序设计语言(K&R)笔记
- 《C程序设计语言》笔记(一)
- 《C程序设计语言》笔记(二)
- 《C程序设计语言》笔记(三)
- 【C程序设计语言】第二章 - 笔记
- 【C程序设计语言】第三章-笔记
- MyEclipse hangs on startup Loading org.maven.ide.eclipse
- 大学毕业后拉开差距的真正原因
- 从1到n的一个序列依次入栈,则一共可能有多少种出栈方式?
- 哈佛大学公开课《Positive Psychology 1504》学习笔记 - Goal Setting
- ORACLE 中rowid查询重复记录的sql语句分析
- c程序设计语言笔记3
- javaweb开发之---在线图书管理系统
- Java:使用Executors创建和管理线程
- 黑马程序员——ADO.net基础知识
- 读书笔记—2012 4 8
- 拿得起,放得下
- 理解指针之基础篇
- Java:使用Executors创建和管理线程
- POJ 1273 最大流模板题