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

  (如果比较操作的代价比交换操作大的话,可以采用二分查找法来减少比较操作的数目。该算法可以认为是插入排序的一个变种,称为二分查找排序。)

C代码  收藏代码
  1. void insertSort(char array[], int n)  
  2. {  
  3.     int i,j;  
  4.     int temp;  
  5.     for(i=0;i<n;i++)  
  6.     {  
  7.         temp=array[i];  
  8.         for(j=i; j>0 && temp<array[j-1];j--)  
  9.             array[j]=array[j-1];  
  10.         array[j]=temp;  
  11.     }  
  12. }  


练习3-3 编写函数expand(s1,s2),将字符串s1中类似于a-z一类的速记符号在字符串s2中还原。

#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;}}



原创粉丝点击