面试中的算法
1.快速排序
template<typename T>
//分为两部分,一部分小于arr[l],另一部分大于arr[l],返回分割的index int __partition(T* arr,int l,int r) { //[l+1,j]<arr[l] //[j+1,i-1] >arr[l] T v = arr[l]; int j = l; for(int i = l+1; i <= r;i++) { if(arr[i] < v) { j++; swap(arr[j],arr[i]); } } swap(arr[l],arr[j]); return j; } //递归调用,对于[l,r] template<typename T> void __quickSort(T* arr,int l,int r) { //递归结束条件
if(l >= r) return; // if(r - l <= 15) // { // Sort::insertionSort(arr,l,r); // return; // } int q = __partition(arr,l,r); __quickSort(arr,l,q - 1); __quickSort(arr,q + 1,r); } template<typename T> void quickSort(T* arr,int n) { __quickSort(arr,0,n-1); } }
2.插入排序
template<typename T> void insertionSort(T arr[], int n) { for(int i = 1; i < n ; i++) { T e = arr[i]; int j; //当前位置的前一个比要比较的小,则应当前一个元素应该向后移动 for( j = i ; j > 0 && arr[j-1] > e ; j--) { arr[j] = arr[j-1]; } arr[j] = e; } }
3.冒泡排序
template<typename T> void bubbleSort(T* a, int n) { assert(arr); int i = 0, j = 0; int k = n - 1,pos = 0;//pos变量用来标记循环里最后一次交换的位置 for (i = 0; i < size - 1; i++)//一共要排序size-1次 { //每次遍历标志位都要先置为0,才能判断后面的元素是否发生了交换 bool flag = false; for (j = 0; j <k; j++)//选出该趟排序的最大值往后移动 { if (arr[j] > arr[j + 1]) { T tmp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = tmp; flag = true;//只要有发生了交换,flag就置为1 pos = j;//循环里最后一次交换的位置 j赋给pos } } k = pos; //判断标志位是否为0,如果为0,说明后面的元素已经有序,就直接return if (!flag) { return; } } }
4.字符串拷贝
char* Strcpy(char* dst, char* src) { assert(dst != NULL && src != NULL); // 断言 dst和src不能为NULL char* dst_address = dst; // 保存目的地址 while((*(dst++) = *(src++)) != '\0') { /* do nothing */ } return dst_address; // 返回目的地址 允许链式表达式 }
5.拷贝前n个
char* Strncpy(char* dst, const char* src, size_t num) { assert(dst != NULL && src != NULL); // 断言 dst和src不能为NULL char* dst_address = dst; size_t i = 0; // 控制复制的个数 while(i++ < num && (*dst++ = *src++) != '\0') { /* do nothing */ } if(*dst != '\0') // 字符必须以'\0'结尾 { *dst = '\0'; } return dst_address; }
6.字符串长度
size_t Strlen(const char *str) { assert(str != NULL); int count = 0; while(*str++ != '\0') { ++count; } return count; }
7.内存拷贝
void* Memcpy( void *dest, const void *src, size_t count ) { assert(dest != NULL && src != NULL); char* _dest = (char*)dest; char* _src = (char*)src; while (count--) { *_dest++ = *_src++; } return dest; }
8.内存移动
void * Memmove ( void * destination, const void * source, size_t num ) { char* _dst = NULL; char* _src = NULL; if(destination <= source) { _dst = destination; _src = source; while (num--) { *_dst++ = *_src++; } } else { _dst = destination; _src = source; _dst += num; _src += num; while (num--) { *--_dst = *--_src; } } }
9.二分查找
int BinarySearch( int *pArray, int Count, int Value ) { assert( NULL != pArray ); int Left = 0; int Right = Count -1; int Mid = 0; while( Left <= Right ) { // Mid = ( Left + Right ) / 2; Mid = Left + ((Right - Left)>1); if( Value < pArray[ Mid ] ) { Right = Mid - 1; } else if( Value > pArray[ Mid ] ) { Left = Mid + 1; } else { return Mid; } } return -1; }
10.斐波那契数列
int FibonacciSequence(unsigned int n) { if(1 == n || 0 == n) { return n; } else { return FibonacciSequence(n-1)+FibonacciSequence(n-2); } }
11.链表逆序
struct node { int value; node * next; }; // 链表逆序 node* reverse(node *head) { node *pre,*post,*cur; if(!head && !head->next) return head; pre=head; cur=pre->next; while(cur) { post=cur->next; cur->next=pre; pre=cur; cur=post; } head->next=NULL; return pre; }
递归实现
//不完整
void reverse(Node *pnode) { if(pnode==NULL||pnode->next==NULL) { phead=pnode; return; } reverse(pnode->next); pnode->next->next=pnode; pnode->next=nullptr; }