对数组元素进行排序——指针的应用(2)

问题描述:用指针实现一个给定数组的数组元素的插入法排序

解题思路:
1.为了提高数组元素的输入效率,采用从文件中读取数据,使用freopn()函数。
2.将数组元素分成有序sequence和无序disorder两个部分,设置两个指针sequen_head 和sequen_rear分别指向有序部分的第一个和最后一个元素,再设置两个指针disorder_head和disorder_rear分别指向无序部分的第一个元素和最后一个元素的后面一个位置。
初始时,有序部分只有一个元素(即数组的第一个元素),sequen_head 和sequen_rear都指向该元素;disorder_head指针指向数组的第二个元素;每次从无序的部分拿出第一个元素插入到有序部分,直到无序集为空集,即disorder_head不小于disorder_rear 。
3.插入过程:将待插入元素 disorder_head与有序部分最后一个元素 sequen_rear进行比较,若大于则插入过程结束;若被比较元素sequen_rear是第一个元素,交换两个元素位置,插入结束;否则,将有序集的最后一个元素sequen_rear后移一个位置,然后递归地将待插入元素*disorder_head插入到除最后一个元素之外的有序集。
4.输出排好序的数组元素。
从以上分析过程可以将整个实现过程用四个函数实现,分别是初始化函数initialize()、选择插入元素函数sort()、插入函数insert()和输出函数output()。freopen()函数被初始化函数所调用。

完整代码:

/*问题:给定一个数组,对其数组元素采用插入法进行排序
   Written by: Jimmy Tung
   Date : 2020.04.08
*/
#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 10 //数组元素个数

void initialize( int * , int * ); //初始化数组
void sort( int * , int * ); //排序
void insert( int *, int * , const int ); //将选择的元素插入有序部分
void output( int *, int *); //输出排序结果

int main(void)
{
   int array[MAXSIZE]; //命名数组
   //初始化数组
   initialize( array , *(&array + 1) );
   //排序
   sort( array , *(&array + 1) );
   //输出
   output( array , *(&array + 1) );
   system("PAUSE");
   return 0;
}
//初始化数组{8 9 7 6 5 4 3 2 1 0}
void initialize( int *head , int *rear)
{
   freopen("E:\\测试数据.txt", "r", stdin);
   while( head < rear )
   {
       scanf("%d", head++);
   }
   freopen("CON", "r", stdin);
}
//排序:将数组分为有序sequence和无序disorder两部分
void sort( int *head , int *rear )
{
   int *sequen_head = head, *sequen_rear = head;
   int *disorder_head = head + 1, *disorder_rear = rear;
   while( disorder_head < disorder_rear )
   {
       insert( sequen_head, sequen_rear , *disorder_head);
       sequen_rear++;
       disorder_head++;
   }
}
//递归地将值插入到有序部分
void insert( int *head, int *rear , const int value)
{
   if( value >= *(rear)) //递归终止条件
   {
       return;
   }
   *(rear + 1) = *rear; //向后移动元素
   if( head == rear) //递归终止条件
   {
       *head = value;
   }
   else
       insert( head, rear -1 , value); //递归过程
}
//输出排序结果
void output( int *head, int *rear)
{
   printf("数组排序结果为:");
   while( head < rear)
   {
       printf("%d,", *head++);
   }
   putchar('\n');
}

结果如下:

输入:8, 9, 7, 6, 5, 4, 3, 2, 1, 0
输出:0,1,2,3,4,5,6,7,8,9,
请按任意键继续. . .

Process returned 0 (0x0)   execution time : 6.871 s
Press any key to continue.

要点复盘:
1.sort()函数的参数分析
形参类型都是 int *类型,实参如下。

sort( array , *(&array + 1) );

sort()函数的第一个实参是数组名array,我们知道数组名是一个指向数组起始元素的指针,所以此处的array是一个 int类型的指针,其左值是指向一个大小为sizeof(int)的内存区域,即数组起始元素所占的内存区域,array的值(右值)是该内存区域的第一个内存单元的编号。 array的右值在sort()函数的函数体执行前将会被赋给形参head。
&是求指针运算符,运算对象为左值表达式,所以运算结果&array是指向array数组的一个指针常量,数据类型为 int ( * ) [MAXSIZE]。指针常量&array指向的内存区域大小为sizeof(int)
MAXSIZE。&array + 1 指向下一个类型为 int ( * ) [MAXSIZE],大小和array数组一样大的内存区域。
“ * ”是间接引用运算符,运算对象为指针,运算结果为指针所指向的那块内存或者那块内存中数据的值。所以(&array + 1) 就是array数组后一个与array数组同类型和大小的内存区域。可以认为,(&array + 1)相当于这个数组的数组名,其右值为该数组起始元素第一个内存单元的编号(也是array数组后一个int类型内存区域的地址编号),该值在sort()函数的函数体执行前会被赋给形参rear。可以通过以下代码验证。

printf("%p %p\n", array + MAXSIZE - 1 , *(&array + 1));
printf("%d\n", sizeof *(&array + 1) );

2.insert()函数的分析
先看该函数的实参,首先需要明确一点,实参是右值表达式,将被赋给形参。

insert( sequen_head, sequen_rear , *disorder_head);

前两个参数定位了有序部分的区域,第三个参数*disorder_head在此处是右值的含义,是disorder_head指针所指向的数组元素的值。
再看函数体,两种情况停止递归,分别是当带插入元素值value不小于有序集最后一个元素值和有序集只有一个元素的时候,其余情况再次调用insert()函数完成插入操作。

问题思考:
1.算法上可做哪些优化?
(1)插入过程采用二分插入
2.是否可以减少指针的数量?
(1)有序部分头指针没有用到

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,240评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,328评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,182评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,121评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,135评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,093评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,013评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,854评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,295评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,513评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,398评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,989评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,636评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,657评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容