指针、快速排序

一)指针

1.指针变量初始化

(1)如果指针变量没有初始化,此时是随机值。初始化可以让指针变量有明确指向。

eg:①int  a = 10;

          int  *p = &a;

②int  *p = NULL; //0号地址 ---- 空指针

(2)赋值:

方式①:  int  *p;    p=NULL;

方式②:  int a;   int *p;  p = &a;

方式③:int  *p,q;   // p是指针类型 int * ;q是int型

方式④:int  *p,*q;    //此时表示定义了两个int * 类型的变量p , q(同时定义多个指针类型)

注意:定义时候的 * ,修饰变量名的时候 表示定义的是一个指针类型的变量。

要实现被调修改主调

2.指针作为函数参数

(1)形参:指针类型变量,用来接收实参(实参是 要操作的内存空间的地址)

(2)实参:要修改谁,就把谁的地址传过去。(但是要保证空间有效)

注意:被调函数中一定要有 *p 运算(间接访问的操作)

(3)传参方式:①值传递:只是把实参数据赋值给了形参;②地址(指针)传递:传的是地址(可以实现被调修改主调)

(二)指针+一维整型数组

eg:int a[5];   //一维整型数组:

                       //数组名;

                       //类型:数据类型int[5] ;

                       //值:数组首元素地址(常量)

                       //数组名是常量,不能做自增、自减运算

1.定义一个什么类型的指针变量?  int  *p = a;  或  int  *p = &a[0];   (a是数组)

2.谁能代表数组所在空间的首地址? 数组名 -- 数组首元素的地址

eg:   int  *p = a;  //表示 p 指向了数组 a,  此时 *p <=> a[0]

3.指针的其它运算:

(1)p+1:当对指针 p 执行 p + 1 操作时,如果 p 指向的是某个基类型(如整数、字符等)的变量,那么 p + 1 会使指针跳过 sizeof(基类型) 个字节,指向同类型的下一个元素。这是因为指针的运算会根据所指向的数据类型的大小进行相应的偏移。

(2)p-1:与 p + 1 相反,p - 1 会使指针向前移动 sizeof(基类型) 个字节,指向同类型的前一个元素。

(3)p++:指针的后置自增运算。先使用 p 的当前值进行操作,然后将 p 的值增加 sizeof(基类型) 个字节,指向下一个同类型的元素。

(4)p-- :指针的后置自减运算。先使用 p 的当前值进行操作,然后将 p 的值减少 sizeof(基类型) 个字节,指向上一个同类型的元素。

(5)比较:>  <  >=  <=  ==   !=  (比较地址编号)

         当对指针进行比较操作(><>=<===!= )时,实际上是比较它们所指向的内存地址的编号。只有当两个指针指向同一块内存区域(例如,指向同一个数组)时,进行比较才有实际意义。如果两个指针指向不同的内存区域或不同类型的对象,比较的结果是未定义的。

注意:

(1)当 p 是指针类型变量:

①  *&p:&p 表示取指针 p 的地址, *&p 就是对 p 的地址进行解引用,结果仍然是 p 本身。

②  &*p:*p 表示访问指针 p 所指向的内容, &*p 就是取 p 所指向内容的地址。如果 p 指向一个变量 x ,那么 &*p 就等于 &x。

(2)当 p 是指针类型变量,a 是数组时:(<=>  --- 等价)

① *(p+i) <=> a[i] <=> *(a+i)

② a[i]  <=> *(a+i)

③ i[a]  <=> *(i+a)      

(3)若 p 和 q 是指针类型变量:

    在 C 或 C++ 中,对于指针类型的变量 p 和 q ,通常不允许进行 p - qp + qp * q 和

 p / q 这样的运算。指针的主要操作是基于地址的偏移(如 p + n 或 p - n ,其中 n 为整数,表示移动的元素个数)和比较(如 p == q 、 p < q 等),如果对指针进行上述不被允许的数学运算(如 p - qp + qp * q 、p / q),编译器会报错。

4.数组作为函数参数

(1)形参:数组形式(本质上是一个指针类型变量);数组长度

(2)实参:数组名(数组名代表数组首地址); 数组长度

(三)快速排序

思想:分而治之

1.实现思想

选择一个基准元素,通过一趟排序将待排序的序列分割成独立的两部分,其中一部分的所有元素都比基准元素小,另一部分的所有元素都比基准元素大。然后对这两部分分别进行快速排序,从而实现整个序列的有序。

2.实现步骤

(1)选择基准元素:通常从待排序序列中选择第一个元素作为基准值。

(2)分区操作:

从序列的两端开始,设置两个指针 begin 和 end 。                       

指 begin 针从左向右移动,直到找到第一个大于等于基准的元素;end 指针从右向左移动,直到找到第一个小于等于基准的元素。

交换这两个元素的位置。

重复②-③步骤,直到 end 指针与 begin 指针相遇。

最后将基准元素与 end 指针所指向的元素交换位置,此时 end 指针之前的元素都小于等于基准,end 指针之后的元素都大于等于基准,完成分区。

(3)对分区后的两部分分别递归地进行快速排序:对小于基准的子序列和大于基准的子序列分别再次执行上述步骤,直到整个序列有序。

(3)具体代码
void quickSort(int *begin, int *end)
{
	int *p = begin;
	int *q = end;

	int *k = begin;

	if(begin>=end)
	{
		return;
	}

	while(begin<end)
	{
		while(begin<end && *end>=*k)
		{
			--end;
		}
		while(begin<end && *begin<=*k)
		{
			++begin;
		}
		swap(begin,end);
	}
	swap(k,begin);
	quickSort(p,end-1);
	quickSort(begin+1,q);
}

  • 11
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值