1、 对以下一组数据进行降序排序(冒泡排序)。
#pragma mark- 1:冒泡排序
- (void)Algorithm0 {
int array[10] = {45, 3, 56, 13, 9, 23, 88, 17, 5, 77};
int num = sizeof(array)/sizeof(int);
for(int i = 0; i < num-1; i++) {
for(int j = 0; j < num - 1 - i; j++) {
if(array[j] < array[j+1]) {
int tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
}
}
}
printf("冒泡排序:");
for(int i = 0; i < num; i++) {
printf("%d", array[i]);
if(i == num-1) {
printf("\n");
} else {
printf(" ");
}
}
}
//测试结果:
2、 对以下一组数据进行升序排序(选择排序)。
#pragma mark- 2:升序排序(选择排序)
- (void)Algorithm1 {
int numArr[10] = {45, 3, 56, 13, 9, 23, 88, 17, 5, 77};
sort(numArr, 10);
for (int i = 0; i < 10; i++) {
printf("%d, ", numArr[i]);
}
printf("\n");
}
void sort(int a[],int n) {
int i, j, index;
for(i = 0; i < n - 1; i++) {
index = i;
for(j = i + 1; j < n; j++) {
if(a[index] > a[j]) {
index = j;
}
}
if(index != i) {
int temp = a[i];
a[i] = a[index];
a[index] = temp;
}
}
}
//测试结果:
3、 快速排序算法
#pragma mark- 3:快速排序算法
- (void)Algorithm2 {
int numArr[10] = {45, 3, 56, 13, 9, 23, 88, 17, 5, 77};
sort2(numArr, 0, 9);
printf("快速排序算法:");
for (int i = 0; i < 10; i++) {
printf("%d, ", numArr[i]);
}
printf("\n");
}
//*a 数组 indexMin:开始位置 indexMax:结束位置
void sort2(int *a, int indexMin, int indexMax) {
if(indexMin >= indexMax) {
return ;
}
int i = indexMin;
int j = indexMax;
int key = a[indexMin];
while (i < j) {
while (i < j && key >= a[j]) {
j--;
}
a[i] = a[j];
while (i < j && key <= a[i]) {
i++;
}
a[j] = a[i];
}
a[i] = key;
sort2(a, indexMin, i-1);
sort2(a, i+1, indexMax);
}
//打印结果:快速排序算法:
4、 归并排序
#pragma mark- 4:并归排序
- (void)Algorithm3 {
int numArr[10] = {45, 3, 56, 13, 9, 23, 88, 17, 5, 77};
int tempArr[10];
sort(numArr, tempArr, 0, 9);
printf("并归排序:");
for (int i = 0; i < 10; i++) {
printf("%d, ", numArr[i]);
}
printf("\n");
}
void merge(int sourceArr[], int tempArr[], int startIndex, int midIndex, int endIndex) {
int i = startIndex;
int j = midIndex + 1;
int k = startIndex;
while (i != midIndex + 1 && j != endIndex + 1) {
if (sourceArr[i] >= sourceArr[j]) {
tempArr[k++] = sourceArr[j++];
} else {
tempArr[k++] = sourceArr[i++];
}
}
while (i != midIndex + 1) {
tempArr[k++] = sourceArr[i++];
}
while (j != endIndex + 1) {
tempArr[k++] = sourceArr[j++];
}
for (i = startIndex; i <= endIndex; i++) {
sourceArr[i] = tempArr[i];
}
}
void sort(int souceArr[], int tempArr[], int startIndex, int endIndex) {
int midIndex;
if (startIndex < endIndex) {
midIndex = (startIndex + endIndex) / 2;
sort(souceArr, tempArr, startIndex, midIndex);
sort(souceArr, tempArr, midIndex + 1, endIndex);
merge(souceArr, tempArr, startIndex, midIndex, endIndex);
}
}
5、 二分查找算法
#pragma mark- 5:二分查找算法
- (void)Algorithm4 {
//给定一个排序数组
int numArr[10] = {3, 5, 9, 13, 17, 23, 45, 56, 77, 88};
//从数组中找到目标23
int targetIndex = bsearchWithoutRecursion(numArr, 0, 9, 23);
printf("二分查找算法:");
if (targetIndex >= 0) {
printf("找到目标位置%d, ", targetIndex);
} else {
printf("未找到目标!");
}
printf("\n");
}
int bsearchWithoutRecursion(int array[],int low,int high,int target) {
while(low <= high) {
int mid = (low + high) / 2;
if(array[mid] > target) {
high = mid - 1;
} else if(array[mid] < target) {
low = mid + 1;
} else {//找到
return mid;
}
}
//找不到
return -1;
}
6、递归实现
#pragma mark- 6:递归实现 查找算法
- (void)Algorithm5 {
//给定一个排序数组
int numArr[10] = {3, 5, 9, 13, 17, 23, 45, 56, 77, 88};
//从数组中找到目标23
int targetIndex = binarySearch(numArr, 0, 9, 23);
printf("递归实现查找算法:");
if (targetIndex >= 0) {
printf("找到目标位置%d, ", targetIndex);
} else {
printf("未找到目标!");
}
printf("\n");
}
int binarySearch(const int arr[],int low,int high,int key) {
int mid=low + (high - low) / 2;
if(low > high)
return -1;
else{
if(arr[mid] == key)
return mid;
else if(arr[mid] > key)
return binarySearch(arr, low, mid-1, key);
else
return binarySearch(arr, mid+1, high, key);
}
}
6、 如何实现单链表翻转(链表逆序)
#pragma mark- 7:链表翻转(单链表逆序)
- (void)Algorithm6 {
/*
链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。
链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。
每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,
比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,
而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。
单向链表的反转是一个经常被问到的一个面试题,也是一个非常基础的问题。
比如一个链表是这样的: 1->2->3->4->5 通过反转后成为5->4->3->2->1。
最容易想到的方法遍历一遍链表,利用一个辅助指针,
存储遍历过程中当前指针指向的下一个元素,
然后将当前节点元素的指针反转后,利用已经存储的指针往后面继续遍历。
*/
node *head = createLinkList(7);
if (head) {
printLinkList(head);
node *reHead = reverseFunc1(head);
printLinkList(reHead);
free(reHead);
}
free(head);
}
node *createLinkList(int length) {
if (length <= 0) {
return NULL;
}
node *head,*p,*q;
int number = 1;
head = (node *)malloc(sizeof(node));
head->num = 1;
head->next = head;
p = q = head;
while (++number <= length) {
p = (node *)malloc(sizeof(node));
p->num = number;
p->next = NULL;
q->next = p;
q = p;
}
return head;
}
void printLinkList(node *head) {
if (head == NULL) {
return;
}
node *p = head;
while (p) {
printf("%d ", p->num);
p = p -> next;
}
printf("\n");
}
node *reverseFunc1(node *head) {
if (head == NULL) {
return head;
}
node *p,*q;
p = head;
q = NULL;
while (p) {
node *pNext = p -> next;
p -> next = q;
q = p;
p = pNext;
}
return q;
}
7、 实现一个字符串“how are you”的逆序输出(编程语言不限)。如给定字符串为“hello world”,输出结果应当为“world hello”。
// 对指针p和q之间的所有字符逆序
void ReverseWord(char* p, char* q)
{
while(p < q)
{
char t = *p ;
*p++ = *q ;
*q-- = t ;
}
}
// 将句子按单词逆序
char* ReverseSentence(char* s)
{
// 这两个指针用来确定一个单词的首尾边界
char* p = s ; // 指向单词的首字符
char* q = s ; // 指向空格或者 '\0'
while(*q != '\0')
{
if (*q == ' ')
{
ReverseWord(p, q - 1) ;
q++ ; // 指向下一个单词首字符
p = q ;
}
else
q++ ;
}
ReverseWord(p, q - 1) ; // 对最后一个单词逆序
ReverseWord(s, q - 1) ; // 对整个句子逆序
printf("%s", s);
return s ;
}
8、 给定一个字符串,输出本字符串中只出现一次并且最靠前的那个字符的位置?如“abaccddeeef”,字符是b,输出应该是2。
9、 二叉树
二叉树的遍历大概分为四种: 分别是前序遍历,中序遍历,后序遍历,按层遍历
(1) 前序遍历:根节点------左子树------右子树
结果: A -> ( B -> C -> D ) -> E -> F -> G
(左子树里面循环套用前序遍历法,结果是 B -> C -> D, 其它同理)
(2) 中序遍历:左子树---根节点--右子树
结果: ( C -> B -> D ) -> A -> E -> F -> G
(3) 后序遍历:左子树---右子树---根节点
结果: ( C -> D -> B ) -> G ->F -> E -> A
(4) 按层遍历: 上到下,左到右顺序
结果: A -> B -> E ->C -> D ->F -> G
10、 打印2-100之间的素数。
#pragma mark- 9:求2-100间的 素数
- (void)Algorithm8 {
for (int i = 2; i < 100; i++) {
int r = isPrime(i);
if (r == 1) {
printf("%d ", i);
}
}
}
/*
所谓素数是指除了1和它本身以外,不能被任何整数整除的数,例如17就是素数,因为它不能被2~16的任一整数整除。因此判断一个整数m是否是素数,只需把m被2~m-1之间的每一个整数去除,如果都不能被整除,那么m就是一个素数
另外判断方法还可以简化。m不必呗2~m-1之间的每一个整数去除,只需被2~√m之间的每一个整数去除就可以了。如果m不能被2~√m间任一整数整除,m必定是素数。例如判别17是是否为素数,只需使17被2~4之间的每一个整数去除,由于都不能整除,可以判定17是素数。(原因:因为如果m能被2~m-1之间任一整数整除,其二个因子必定有一个小于或等于√m,另一个大于或等于√m。例如16能被2,4,8整除,16=2*8,2小于4,8大于4,16=4*4,4=√16,因此只需判定在2~4之间有无因子即可)
*/
int isPrime(int n) {
int i;
for(i = 2; i <= sqrt(n); i++) {
if(n % i == 0) {
return 0;
}
}
return 1;
}
11、 求两个整数的最大公约数
#pragma mark- 10:最大公因(约)数 (辗转相除法)
- (void)Algorithm9 {
printf("最大公因数:%d ", maxGcd(18,6));
}
/*
最大公因数,也称最大公约数、最大公因子,指两个或多个整数共有约数中最大的一个。
求最大公约数算法:
(1)辗转相除法
有两整数a和b:
① a%b得余数c
② 若c=0,则b即为两数的最大公约数
③ 若c≠0,则a=b,b=c,再回去执行①
例如求27和15的最大公约数过程为:
27÷15 余12 ,15÷12余3 ,12÷3余0因此,3即为最大公约数
⑵ 相减法
有两整数a和b:
① 若a>b,则a=a-b
② 若a12 ) 15-12=3( 12>3 )
12-3=9( 9>3 ) 9-3=6( 6>3 )
6-3=3( 3==3 )
因此,3即为最大公约数
*/
int maxGcd(int a, int b) {
int temp = 0;
if (a < b) {
temp = a;
a = b;
b = temp;
}
while (b != 0) {
temp = a % b;
a = b;
b = temp;
}
return a;
}
12、 最小公倍数
/*
求最小公倍数算法:
最小公倍数 = 两整数的乘积 ÷ 最大公约数
*/
#pragma mark- 11:最小公倍数
- (void)Algorithm10 {
int A = 18,B = 6;
printf("最小公倍数:%d ", A * B / maxGcd(A,B));
}
13、 题:求一个矩阵中最大的n==2的二维子矩阵(元素和最大).如:
1 2 0 3 4
2 3 4 5 1
1 1 5 3 0
中最大的是:
4 5
5 3
要求:(1)写出算法;(2)分析时间复杂度;(3)用C写出关键代码
分析:方法一、这是最容易想到也是最容易实现的方法。遍历矩阵(行迭代器为i,列迭代器为j),以当前遍历到的元素为首a[i,j],计算二维子矩阵的和(sum=a[i,j]+a[i+1,j]+a[i,j+1]+a[i+1,j+1]),并找出和最大的二维矩阵,注意矩阵的最后一行和最后一列不用遍历。时间复杂度为O(i*j)。
实现代码:
void get_max_22Matrix(int *a,int row,int col,int *result)
//a为原矩阵,row,col指a矩阵的行和列,result存储最终得到的子二维矩阵
{
int maxsum=0,result_i,result_j,sum;
#define a(i,j) *(a+(i)*col+(j)) //用二维的形式表示一维数组,访问需要一定的代价
#define result(i,j) *(result+(i)*2+(j))
for(int i=0; i
14、输入n个整数,输出其中最小的k个
/思路:把输入的n个整数排序,排在最前面的k个数就是最小的k个数。时间复杂度为O(nlogn)/
#include
#include
#include
using namespace std;
//bool cmp(int &a, int &b)
//{
// return a < b;
//}
int main()
{
int n,k;
cin >> n;
cin >> k;
vector array;
for (int i = 0; i < n;i++)
{
int m;
cin >> m;
array.push_back(m);
}
sort(array.begin(),array.end());//sort默认就是升序(从小到大),不用重载cmp
for (int i = 0; i < k;i++)
{
cout << array[i];
if (i == k - 1) //注意最后一个数输出后不能有空格
{
cout << endl;
continue;
}
cout << ' ';
}
return 0;
}
参考:
1: http://blog.csdn.net/yangshebing21/article/details/51292477
2: http://www.jianshu.com/nb/2488809
3: