1.字符串翻转
char str[] = "abcde";
reservString(str);
reservString具体实现如下
void reservString(char* str){
//算法基本思路就是头尾指针指向字符串的头部和尾部,然后依次交换头尾指针的值。循环的终止条件是头指针小于尾指针
char* begin = str;
char* end = str + strlen(str) - 1;
while (begin < end) {
char temp = *begin;
*(begin++) = *end;
*(end--) = temp;
}
printf("%s",str); //输出edcba
}
2.链表原地翻转
//定义一个链表节点
struct Node{
int data;
struct Node *next;
};
//几个链表操作的基本方法
//1构建一个链表
struct Node* constructList(void){
struct Node* head = NULL;
struct Node* cur = NULL;
for (int i = 0; i < 10; i++) {
struct Node* node = malloc(sizeof(struct Node));
node->data = rand() % 100;
if(head == NULL){
head = node;
}else{
cur->next = node;
}
//设置当前节点为新节点
cur = node;
}
cur->next = NULL;
return head;
}
//2.打印一个链表
void printList(struct Node* head){
struct Node* cur = head;
while (cur != NULL) {
printf("%d->",cur->data);
cur = cur->next;
}
printf("NULL\n");
};
//3.原地翻转链表并返回新链表的头结点,头插法
struct Node* reverseList(struct Node* head){
struct Node* p = head;
struct Node* newH = NULL;
while (p != NULL) {
struct Node* temp = p;
p = p->next;
temp->next = newH;
newH = temp;
}
return newH;
}
//测试代码
struct Node* head = constructList();
printList(head);
//打印出来:7->49->73->58->30->72->44->78->23->9->NULL
struct Node* newH = reverseList(head);
printList(newH);
//打印结果:9->23->78->44->72->30->58->73->49->7->NULL
3.合并有序数组,尽可能快
void chainSortArray(int aArray[], int aLen,int bArray[],int bLen,int result[]){
int aIndex = 0;
int bIndex = 0;
int sortIndex = 0;
while (aIndex < aLen && bIndex < bLen) {
if(aArray[aIndex] < bArray[bIndex]){
result[sortIndex] = aArray[aIndex];
aIndex++;
}else{
result[sortIndex] = bArray[bIndex];
bIndex++;
}
sortIndex++;
}
//将剩下没有比较完的数组的东西放到数组中
while (aIndex < aLen) {
result[sortIndex] = aArray[aIndex++];
sortIndex++;
}
while (bIndex < bLen) {
result[sortIndex] = bArray[bIndex++];
sortIndex++;
}
}
//测试用例ex:
int a[] = {0,8,9,10,13,16};
int b[] = {1,4,7,8,45};
int result[11] = {0};
chainSortArray(a, 6, b, 5, result);
for (int i = 0; i < 11; i++) {
printf("%d,",result[i]);
//打印结果:0,1,4,7,8,8,9,10,13,16,45,
}
4.查找一个字符串中第一个出现1次的字符
char hashFind(char *str){
//采用hash算法的思想 hash算法就是字符ascii码就是对应的hash index
int array[256] = {0};
char *p = str;
while (*p != '\0') {
array[*p]++;
p++;
}
p = str;
//**这里注意** 这里是遍历原来的字符数组,而不是遍历hash 数组
while (*p != '\0') {
if(array[*p] == 1){
return *p;
}
p++;
}
return *p;
}
5.求x的n次方
//递归的思想,而且需要考虑边界条件
double qart(double x, int n){
if(n == 0){
return 1;
}else if(n > 0){
return qart_sub(x, n);
}else{
return 1 / qart_sub(x, abs(n));
}
}
double qart_sub(double x, int n){
if(n == 0){
return 1;
}else {
return x * qart(x, n - 1);
}
return x;
}
//测试用例ex:
double res = qart(2, -5);
printf("结果为:%.6f\n",res); //结果为:0.031250
6.写一个快速排序
//将从left起到right的子数组 做中间元素的分割
int partition(int arr[], int left, int right){
int i = left;
int j = right;
int tmp = arr[left];
while (i < j) {
//从右往左扫描
while (i < j && arr[j] > tmp) {
j--;
}
//遇到比分割元素小的元素,将元素挪到数组左边填坑
if(i < j){
arr[i] = arr[j];
i++;
}
//从左往右扫描
while (i < j && arr[i] < tmp) {
i++;
}
//遇到比b分割元素大的元素,将元素挪到数组右边填坑
if(i < j){
arr[j] = arr[i];
j--;
}
}
//放置分割元素,arr[left,i-1] 全部小于 arr[i] arr[i+1,right]全部大于arr[i]
arr[i] = tmp;
return i;
}
void quickSort(int array[],int left, int right){
if (left > right)
return;
int j = partition(array, left, right);
//分治法,划分子问题,递归解决子问题
quickSort(array, left, j-1);
quickSort(array, j+1, right);
}
//测试ex:
int arrayEx[20] = {0};
for (int i = 0; i < 20; i++) {
arrayEx[i] = arc4random() % 100;
}
quickSort(arrayEx, 0, 19);
for(int i = 0; i < 20; i++){
printf("%d,",arrayEx[i]);
}
//输出:8,11,12,20,20,28,43,46,48,52,55,65,66,70,72,74,76,78,80,99,
7.求一个无序数组的中位数
// 使用快速排序的思想,左右交替扫描
int findMedianNumber(int array[], int aLen){
//中位数的在数组中的index
int mid = (aLen - 1)/2;
//利用快排的分割思想
int div = partition(array, 0, aLen - 1);
while (mid != div) {
if(mid < div){
div = partition(array, 0, div - 1);
}else{
div = partition(array, div + 1, aLen - 1);
}
}
return array[mid];
}
//测试用例ex:
int array2[] = {2,13,9,5,7,20,18,3,8,10};
int median = findMedianNumber(array2, 10);
printf("中位数%d",median);
//输出 8
8.求一个链表的中间节点
//采用快慢指针的方式
//返回中间节点
struct Node* findLinkMedian(struct Node *head){
//一次走一步
struct Node* slowPtr = head;
//一次走两步
struct Node* fastPtr = head;
while (fastPtr != NULL) {
//当快指针走到最后的时候,慢指针指向的就是中间节点
if(fastPtr->next == NULL){
break;
}
slowPtr = slowPtr->next;
fastPtr = fastPtr->next->next;
}
return slowPtr;
}
//测试代码ex:用到了前面2链表翻转的数据结构和方法
struct Node *head1 = constructList();
printList(head1);
struct Node* medianNode = findLinkMedian(head1);
printf("中间节点是 %d",medianNode->data);
//答应结果:
//3->69->9->57->60->33->99->78->16->35->97->26->12->67->10->33->79->49->79->21->NULL
//中间节点是 97
9.求两个view的共同父视图
10.检测链表中是否有环
//链表中环的检测
int isHaveCircleInList(struct Node *head){
//定义两个指针 快慢指针 如果快慢指针能相遇 说明有环的存在
if (head == NULL) {
return 0;
}
if(head->next == NULL){
return 0;
}
struct Node* slowHead = head;
struct Node* fasthead = head;
while (slowHead != NULL && fasthead != NULL) {
slowHead = slowHead->next;
fasthead = fasthead->next->next;
if(slowHead == fasthead){
return 1;
}
}
return 0;
}
11.两个有序链表的合并
//两个有序的链表合并
struct Node* mergerTwoOrderList(struct Node* list1, struct Node* list2){
if(list1 == NULL){
return list2;
}
if(list2 == NULL){
return list1;
}
struct Node *cur1 = list1;
struct Node *cur2 = list2;
struct Node *newHead = NULL;
struct Node *cur = NULL;
while (cur1 != NULL && cur2 != NULL) {
if(cur1->data < cur2->data){
if(newHead == NULL){
newHead = cur1;
cur = newHead;
}else{
cur->next = cur1;
cur = cur1;
}
cur1 = cur1->next;
}else{
if(newHead == NULL){
newHead = cur2;
cur = newHead;
}else{
cur->next = cur2;
cur = cur2;
}
cur2 = cur2->next;
}
}
while (cur1 != NULL) {
cur->next = cur1;
cur = cur1;
cur1 = cur1->next;
}
while (cur2 != NULL) {
cur->next = cur2;
cur = cur2;
cur2 = cur2->next;
}
cur->next = NULL;
return newHead;
}