仅用 O(1) 的空间,将字符数组按“数字字符”“字母字符”和“其他字符”分成 3 部分并排序,第一部分是数字字符‘0‘-‘9‘,第二部分是字母字符‘a‘-‘z‘和‘A‘-‘Z‘,第三部分是其他字符。

#include <stdio.h>
#include <stdlib.h>

typedef enum{ false = 0, true = 1 } bool;

//两个字符交换 
void swap(char *a, char *b) {
    char c = *a;
    *a = *b;
    *b = c;

//快速排序(从小到大) 
void quickSort(char *arr, int l, int r) {
    //l(left)左边界,r(right)右边界,i:左指针,j:右指针
    if(l < r) { 
        int i = l;
        int j = r;
        char key = arr[l];        //基准值
        while(i < j) {
            while(i < j && arr[j] >= key) {
                j--;            //j定位到小于基准值的值 
            }
            while(i < j && arr[i] <= key) {
                i++;            //i定位到大于于基准值的值 
            }
            if (i < j) {
                swap(arr + i, arr + j);        //交换 
            }
        } 
        arr[l] = arr[i];
        arr[i] = key;            //当i,j相等,将基准值和中间值交换(类似于二分法) 
        quickSort(arr, l, j - 1);        
        quickSort(arr, j + 1, r);        //将中值分开的左右两堆进行排序 
    }
}

//判断字符值是否在ascii码区间内 
bool judge(char c, int l, int r) {
    if(c >= l && c <= r) return true;
    else return false;
}

//将不同字符分类 
void classify(char *arr, int l, int r, int keyl, int keyr) {
    //l(left)左边界,r(right)右边界,i:左指针,j:右指针,keyl-keyr:ascii码区间内放在左部分 
    int i = l;
    int j = r;
    while(i < j) {
        while(i < j && !judge(arr[j], keyl, keyr)) {
            j--;            //j定位到ascii码区间内的字符 
        }
        while(i < j && judge(arr[i], keyl, keyr)) {
            i++;            //i定位到ascii码区间外的字符 
        }
        if (i < j) {
            swap(arr + i, arr + j);        //交换
        }
    } 
}

//将字符数组按“数字字符”“字母字符”“其他字符”排序 
void function(char *arr) {
    int length;                                    //计算字符串总长度 
    for(length = 0; arr[length] != '\0'; length++);
    classify(arr, 0, length - 1, 48, 57);        //将数字字符放在从arr+0开始的单元 
    int end;                                    //计算数字字符数量 
    for(end = 0; judge(arr[end], 48, 57); end++);
    quickSort(arr, 0, end - 1);                    //数字字符排序
    
    classify(arr, end, length - 1, 97, 122);    //将小写字母字符放在从arr+end开始的单元 
    int start = end;
    for(; judge(arr[end], 97, 122); end++);        //计算小写字母的起始位置 
    quickSort(arr, start, end - 1);                //数小写字母字符排序
    
    classify(arr, end, length - 1, 65, 90);        //将大写字母字符放在从arr+end开始的单元 
    start = end;
    for(; judge(arr[end], 65, 90); end++);        //计算大写字母的起始位置 
    quickSort(arr, start, end - 1);                //大写字母字符排序
    
    quickSort(arr, end, length - 1);            //其他字符按ascii码排序
}

int main() {
    printf("示例字符串:qweRtUhgY%98^&-=/ LK~mkBCAlio142 %#@w$S7*iloveU\n");
    char ex[100] = "qweRtUhgY%98^&-=/ LK~mkBCAlio142 %#@w$S7*iloveU";
    function(ex);
    printf("\n排序后的字符串:%s\n", ex);
    printf("\n--------开始用户操作--------\n");
    char arr[1000];
    printf("请输入字符串:");
    gets(arr);
    function(arr);
    printf("\n排序后的字符串:%s\n", arr);
    
    return 0;
}

#include <stdio.h>
#include <stdlib.h>

typedef enum{ false = 0, true = 1 } bool;

//两个字符交换 
void swap(char *a, char *b) {
	char c = *a;
	*a = *b;
	*b = c;
} 

//快速排序(从小到大) 
void quickSort(char *arr, int l, int r) {
	//l(left)左边界,r(right)右边界,i:左指针,j:右指针
	if(l < r) { 
		int i = l;
		int j = r;
		char key = arr[l];		//基准值
		while(i < j) {
			while(i < j && arr[j] >= key) {
				j--;			//j定位到小于基准值的值 
			}
			while(i < j && arr[i] <= key) {
				i++;			//i定位到大于于基准值的值 
			}
			if (i < j) {
				swap(arr + i, arr + j);		//交换 
			}
		} 
		arr[l] = arr[i];
		arr[i] = key;			//当i,j相等,将基准值和中间值交换(类似于二分法) 
		quickSort(arr, l, j - 1);		
		quickSort(arr, j + 1, r);		//将中值分开的左右两堆进行排序 
	}
}

//判断字符值是否在ascii码区间内 
bool judge(char c, int l, int r) {
	if(c >= l && c <= r) return true;
	else return false;
}

//将不同字符分类 
void classify(char *arr, int l, int r, int keyl, int keyr) {
	//l(left)左边界,r(right)右边界,i:左指针,j:右指针,keyl-keyr:ascii码区间内放在左部分 
	int i = l;
	int j = r;
	while(i < j) {
		while(i < j && !judge(arr[j], keyl, keyr)) {
			j--;			//j定位到ascii码区间内的字符 
		}
		while(i < j && judge(arr[i], keyl, keyr)) {
			i++;			//i定位到ascii码区间外的字符 
		}
		if (i < j) {
			swap(arr + i, arr + j);		//交换
		}
	} 
}

//将字符数组按“数字字符”“字母字符”“其他字符”排序 
void function(char *arr) {
	int length;									//计算字符串总长度 
	for(length = 0; arr[length] != '\0'; length++);
	classify(arr, 0, length - 1, 48, 57);		//将数字字符放在从arr+0开始的单元 
	int end;									//计算数字字符数量 
	for(end = 0; judge(arr[end], 48, 57); end++);
	quickSort(arr, 0, end - 1);					//数字字符排序
	
	classify(arr, end, length - 1, 97, 122);	//将小写字母字符放在从arr+end开始的单元 
	int start = end;
	for(; judge(arr[end], 97, 122); end++);		//计算小写字母的起始位置 
	quickSort(arr, start, end - 1);				//数小写字母字符排序
	
	classify(arr, end, length - 1, 65, 90);		//将大写字母字符放在从arr+end开始的单元 
	start = end;
	for(; judge(arr[end], 65, 90); end++);		//计算大写字母的起始位置 
	quickSort(arr, start, end - 1);				//大写字母字符排序
	
	quickSort(arr, end, length - 1);			//其他字符按ascii码排序
}

int main() {
	printf("示例字符串:qweRtUhgY%98^&-=/ LK~mkBCAlio142 %#@w$S7*iloveU\n");
	char ex[100] = "qweRtUhgY%98^&-=/ LK~mkBCAlio142 %#@w$S7*iloveU";
	function(ex);
	printf("\n排序后的字符串:%s\n", ex);
	printf("\n--------开始用户操作--------\n");
	char arr[1000];
	printf("请输入字符串:");
	gets(arr);
	function(arr);
	printf("\n排序后的字符串:%s\n", arr);
	
	return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Leisure_水中鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值