您的位置:首页 > 理论基础 > 数据结构算法

数据结构与算法练习

2012-02-03 07:33 190 查看
/*

操作单链表(按升序插入节点、删除、反序排列)

*/

#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);
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: