数据结构与算法练习
2012-02-03 07:33
190 查看
/*
操作单链表(按升序插入节点、删除、反序排列)
*/
/*
双向链表的增、删实现,调用者要保证传递正确的参数。
双向链表的头指针结构value用不到,主要是用bk指向第一个节点,bf指向最后一个节点。
*/
//在一个数组中查找给定的值的位置(此数组必须是排好序的),用对分查找实现:O(logN)运行时间的增长是对数级的,效率很高。
//返回最大子序列和(只用一次循环且不用递归,效率特别高),O(N)运行时间是线性的。比如:1 2 -4 5 -1 3 -8 6 此数列的最大子序列和是7(从5到3)。
//求两个正整数的最大公因数(用欧几里得算法求解) 效率:O(logN)很高
排序:
//冒泡排序
//插入排序
//快速排序
操作单链表(按升序插入节点、删除、反序排列)
*/
#include <stdio.h> #include <stdlib.h> typedef struct NODE{ int id; struct NODE *next; } Node, *PLnode;
//插入节点,成功返回0,失败返回-1;(传结构体指针的指针,就不用保存前一个节点) int linkInsert(register PLnode *pp, int value) { Node *node; if (!pp) return -1; while (*pp && (*pp)->id < value) { pp = &(*pp)->next; } node = malloc(sizeof(Node)); if (!node) { return -1; } node->id = value; node->next = *pp; *pp = node; return 0; } //删除节点成功返回0,失败返回-1 int linkDel(PLnode *head, int value) { Node *p, *temp; if (!head || !*head) return -1; while (p = *head) { if (p->id == value) { temp = p; *head = p->next; free(temp); return 0; } head = &(p->next); } return -1; } //反向排列链表(思路:往前插入实现),返回头结点。 PLnode linkReverse(Node *node) { Node *head = NULL; Node *temp; //记录当前节点的下一个节点 if(!node) return NULL; while (node) { temp = node->next; node->next = head; head = node; node = temp; } return head; }
/* 计算链表的实际大小 */ #include"head.h" int linkSum(Node *head) { int s = 0; while(head) { s++; head = head->next; } return s; }
/*
双向链表的增、删实现,调用者要保证传递正确的参数。
双向链表的头指针结构value用不到,主要是用bk指向第一个节点,bf指向最后一个节点。
*/
typedef struct dbLink { unsigned int value; struct dbLink *bf; //指向前面节点的指针 struct dbLink *bk; //指向后面节点的指针 } dbNode, *PLdbNode;
//插入节点,成功返回0,失败返回-1;(当链表中有此节点时就不用插入,直接返回-1) int insertDB(register PLdbNode phead, unsigned int value) { PLdbNode newNode; PLdbNode bkNode; //新节点插入到bfNode和bkNode之间 PLdbNode bfNode; if(!phead) return -1; for (bfNode=phead; bkNode = bfNode->bk; bfNode = bkNode) { if(value == bkNode->value) return -1; else if(value < bkNode->value) break; } newNode = malloc(sizeof(dbNode)); if (!newNode) return -1; newNode->value = value; newNode->bk = bkNode; bfNode->bk = newNode; if (bfNode==phead) //如果新节点不在中间或者首部后面还有节点 newNode->bf = NULL; else //如果新节点在尾部或者首部后面没节点 newNode->bf = bfNode; if (bkNode) bkNode->bf = newNode; else phead->bf = newNode; return 0; } //删除节点成功返回0,失败返回-1; int delDB(register PLdbNode phead, unsigned int value) { PLdbNode bkNode; PLdbNode bfNode; if (!phead) return -1; for (bfNode=phead; bkNode=bfNode->bk; bfNode=bkNode) { if (value == bkNode->value) break; } bfNode->bk = bkNode->bk; bkNode->bk->bf = bfNode; free(bkNode); return 0; }
//在一个数组中查找给定的值的位置(此数组必须是排好序的),用对分查找实现:O(logN)运行时间的增长是对数级的,效率很高。
main(){ int a[8] = {4,5,6,7,8,9,10,11}; printf("10在第%d位。\n",binarySearch(a, 8, 10)); return 0; } int binarySearch(int a[], int len, int n){ int mid, low = 0, high = len-1; while(low <= high){ mid = (low+high) >> 1; //现在确定low+high的和是正整数,所以用移位比除法效率高 if(n < a[mid]) high = mid - 1; else if(n > a[mid]) low = mid + 1; else return mid; } return NOTFOUND; }
//返回最大子序列和(只用一次循环且不用递归,效率特别高),O(N)运行时间是线性的。比如:1 2 -4 5 -1 3 -8 6 此数列的最大子序列和是7(从5到3)。
main(){ int a[8] = {1,2,-4,5,-1,3,-8,6}; printf("%d \n", maxSubSequenceSum(a,8)); return 0; } //联机算法:在任何时刻,算法都能对它已经读入的数据给出正确的答案。 int maxSubSequenceSum(int a[], int n){ int i, maxSum, thisSum; maxSum = thisSum = 0; for(i=0; i<n; i++){ thisSum += a[i]; if(thisSum > maxSum) maxSum = thisSum; else if(thisSum < 0) //thisSum的值小于0时,从下一个数开始从新计算子序列和。 thisSum = 0; } return maxSum; }
//求两个正整数的最大公因数(用欧几里得算法求解) 效率:O(logN)很高
main(){ printf("16和24最大公约数位:%d \n",gcd(16,24)); return 0; } unsigned int gcd(unsigned int m, unsigned int n){ int t1 = m, t2 = n; unsigned int temp; //先求出m和n的大小(让m存大值,n存小值) if(m < n){ t1 = n; t2 = m; } while(t2 > 0){ temp = t1 % t2; t1 = t2; t2 = temp; } return t1; }
排序:
//冒泡排序
void maopao(int a[],int n) { int i, j, t; for(i=1; i<n; i++) { for(j=0; j<n-i; j++) { if(a[j] > a[j+1]) { t = a[j]; a[j] = a[j+1]; a[j+1] = t; } } } }
//插入排序
void chaRu(int a[],int n) { int i, j, temp; for(i=1; i<n; i++){ temp = a[i]; for(j=i; j>0 && temp<a[j-1]; j--){ a[j] = a[j-1]; } a[j] = temp; } }
//快速排序
/***************************************************** 函 数 名:quick_sort 功 能:快速排序 输入参数:arr,要排序的数组;low,低位下标;high,高位下标; 输出参数:空 返 回 值:空 作 者:马文涛 开发时间:2012.2.1 11:46 ******************************************************/ void quick_sort(int *arr, int low, int high) { int temp, l, h; if(low >= high) return; assert(arr != NULL); temp = arr[low]; l = low; h = high; while(l < h) { // 从后向前移动 while(l < h && arr[h] >= temp) h--; if(l < h) arr[l++] = arr[h]; //从前向后移动 while(l < h && arr[l] <= temp) l++; if(l < h) arr[h--] = arr[l]; } //交换中界值和目前l和h相遇位置的值 arr[l] = temp; quick_sort(arr, low, l-1); quick_sort(arr, l+1, high); }
相关文章推荐
- Hark的数据结构与算法练习之奇偶排序
- Hark的数据结构与算法练习之若领图排序ProxymapSort
- 数据结构与算法 LeetCode编程练习--counts Prime
- Hark的数据结构与算法练习之插入排序
- Hark的数据结构与算法练习之臭皮匠排序
- Hark的数据结构与算法练习之多路归并排序
- 数据结构与算法 LeetCode编程练习--Contains Duplicate II
- 数据结构与算法-LeetCode练习二分查找应用
- Hark的数据结构与算法练习之Bogo排序
- Hark的数据结构与算法练习之耐心排序
- 数据结构与算法 LeetCode编程练习--Search in Rotated array
- 数据结构与算法练习-数组查找,排序
- 数据结构与算法练习-回溯、递归
- 数据结构与算法练习
- 数据结构与算法 LeetCode编程练习--Delete Node in a Linked List
- Hark的数据结构与算法练习之地精(侏儒)排序
- Hark的数据结构与算法练习之锦标赛排序
- 数据结构与算法 LeetCode编程练习--Search in Rotated array II
- 数据结构与算法练习Java版练习1.4
- Hark的数据结构与算法练习之计数排序