C语言精典算法

来源:互联网 发布:原油api数据 编辑:程序博客网 时间:2024/05/21 09:24
 

迷宫:

#include <iostream.h>
enum boolean{FALSE, TRUE};
template <class T>
struct Node{
  T val;
  Node *next;
};
template <class T>
class List{
    Node<T> *head;
    int size;
  public:
    List()
    {
      head = NULL;
      size = 0;
    }
  virtual boolean Insert(T val);
  boolean Empty();
  boolean Delete(T val);
  boolean Contains(T val);
  void Print();
  ~List();
};
template <class T>
List<T>::~List()
{
  Node<T> *temp;
  for (Node<T> *p = head; p;){
    temp = p;
    p = p->next;
    delete temp;
  }
}

template <class T>
boolean List<T>::Empty()
{
  if (head)
    return FALSE;
  else
    return TRUE;
}
template <class T>
boolean List<T>::Insert(T x)
{
   Node<T> *node = new Node<T>;
   if (node){
     node->val = x;
     node->next = head;
     head = node;
     size++;
     return TRUE;
   }
   return FALSE;
}

template <class T>
boolean List<T>::Delete(T x)
{
  Node<T> *temp;
  if (Empty())
    return FALSE;
  if (head->val == x){
    temp = head->next;
    delete head;
    size--;
    head = temp;
    return TRUE;
  }
  for (Node<T> *p = temp = head; p; temp = p, p = p->next)
    if (p->val == x){
      temp->next = p->next;
      delete p;
      size--;
      return TRUE;
    }
  return FALSE;
}

template <class T>
boolean List<T>::Contains(T x)
{
  for (Node<T> *p = head; p; p = p->next)
    if (p->val == x)
      return TRUE;
  return FALSE;
}

template <class T>
void List<T>::Print()
{
  for (Node<T> *p = head; p ; p = p->next)
    cout << p->val << "  ";
  cout << " n";
}

void main()
{
  List<int> intlist;
  int i;
  for (i = 0; i < 10; i++)
    intlist.Insert(i);
  intlist.Print();
  intlist.Delete(1);
  intlist.Delete(2);
  intlist.Print();

  List<float> floatlist;
  floatlist.Insert(3.1);
  floatlist.Insert(1.5);
  floatlist.Print();

  List<char *> charlist;
  charlist.Insert("program.");
  charlist.Insert("my ds ");
  charlist.Insert("is ");
  charlist.Insert("This ");
  charlist.Print();
}

#include <stdio.h>
#include <malloc.h>
enum boolean {false, true};
const int MaxSize = 20;
struct celltype{
  int id;
  celltype *next;
};
struct queue{
  celltype *front, *rear;
};
struct EdgeNode{
  int adjvex;
  EdgeNode *next;
};
struct vexNode{
  int info;
  EdgeNode *next;
};
vexNode Graph[MaxSize];
int N;

void MakeNull(queue *head)
{

  head->front->next = NULL;
  head->rear = head->front;
}
void CreateQueue(queue *head)
{
  head->front = (celltype*) malloc (sizeof(celltype));
  head->rear = (celltype*) malloc (sizeof(celltype));
  MakeNull(head);
}
boolean IsEmpty(queue *head)
{
  if (head->front == head->rear)
    return true;
  else
    return false;
}
void Dequeue(queue *head)
{
  celltype *t;
  if (!IsEmpty(head)){
    t = head->front;
    head->front = head->front->next;
    free(t);
  } else
    printf("%s", "DeleteError!");
}
void Enqueue(queue *head, int id)
{
  head->rear->next = (celltype*) malloc (sizeof(celltype));
  head->rear = head->rear->next;
  head->rear->id = id;
}

void CreateGraph()
{
  int i,k;
  EdgeNode *p;
  printf("%s", "Please Input MaxNode = ");
  scanf("%d", &N);
  for (i = 0; i < N; i++){
    Graph[i].info = i;
    printf("%s %d n", "Input Node", i,"'s adjvexNode =  ,input -1 for end");
    scanf("%d", &k);
    if (k >= 0){
      Graph[i].next = (EdgeNode*) malloc (sizeof(EdgeNode));
      p = Graph[i].next;
      p->adjvex = k;
      p->next = NULL;
    }
    while (k >= 0){
      scanf("%d", &k);
      if (k >= 0){
 p->next = (EdgeNode*) malloc (sizeof(EdgeNode));
 p = p->next;
 p->adjvex = k;
      }
    }
    p->next = NULL;
  }
}
void Print()
{
  int i;
  EdgeNode *p;
  for (i = 0; i < N; i++){
    printf("%s %d %s ", "Node ", i, "'s adjvex = ");
    for (p = Graph[i].next; p; p = p->next)
      printf("%d  ", p->adjvex);
    printf(" n");
  }
}
void BFS()
{
  void Search(int, boolean *);
  boolean visited[MaxSize];
  int i;
  for (i = 0; i < N; i++)
    visited[i] = false;
  for (i = 0; i < N; i++)
    if (!visited[i])
      Search(0, visited);
}
void Search(int i, boolean *visited)
{
  queue *Q;
  celltype *p;
  EdgeNode *adj;
  CreateQueue(Q);
  Enqueue(Q, i);
  visited[i] = true;
  printf("%d ", i);
  while (!IsEmpty(Q)){
    p = Q->front->next;
    adj = Graph[p->id].next;
    while (adj){
      if (!visited[adj->adjvex]){
 Enqueue(Q, adj->adjvex);
 printf("%d ", adj->adjvex);
 visited[adj->adjvex] = true;
      }
      adj = adj->next;
    }
    Dequeue(Q);
  }
}
void main()
{
  CreateGraph();
  BFS();
}

这是N皇后问题的回溯法,非递归实现.此算法对初学者有难度,最好去参考书.这个问题也是回溯法的经典例题,推荐自己去实践.还有,我贴的程序在TC3.0下调试通过.
#include <iostream.h>
#include <stdio.h>
#include <math.h>
#include <dos.h>
enum bool{false, true};
class Queen{
  friend int nQueen(int);
  private:
    inline bool Place(int k);
    void Backtrack(void);
    int n, *x;
    long sum;
};
inline bool Queen::Place(int k)
{
  int j;
  for (j = 1; j < k; j++)
    if ((abs(k - j) == abs(x[j] - x[k])) || (x[j] == x[k])) return false;
  return true;
}
void Queen::Backtrack(void)
{
  x[1] = 0;
  int k = 1;
  while (k > 0){
    x[k] += 1;
    while ((x[k] <= n) && !(Place(k)))
      x[k] += 1;
    if (x[k] <= n)
      if (k == n)
 sum++;
      else {
 k++;
 x[k] = 0;
      }
    else
      k--;
  }
}

int nQueen(int n)
{
  Queen X;
  X.n = n;
  X.sum = 0;
  int *p = new int[n+1];
  for (int i = 0; i <= n; i++)
    p[i] = 0;
  X.x = p;
  X.Backtrack();
  delete []p;
  return X.sum;
}
int main()
{
  int n;
  struct time t1, t2; //取系统时间.
  gettime (&t1);
  cout << "input n = ";
  cin >> n;
  cout << nQueen(n) << endl;
  gettime (&t2);
  cout << (t2.ti_sec - t1.ti_sec) + (t2.ti_hund-t1.ti_hund)*1.0/100;
  return 0;
}

2进制的高精度加,减和乘法的C++程序.

  while (len > 1 && C.s[len-1] == 0)
    --len;
  C.len = len;
  return C;
}
hp hp::operator = (hp C)
{
  int i;
  len = C.len;
  for (i = 0; i < MAXSIZE; i++)
    s[i] = C.s[i];
  return *this;
}
int main()
{
  hp A, B, C;
  cin >> A >> B;
  C = A+B;
  cout << A << ‘+’ << B << “ = “ << C << endl;
  C = A-B;
  cout << A << ‘-’ << B << “ = “ << C << endl;
  C = A*B;
  cout << A << '*' << B << " = " << C << endl;   
  return 0; 
}

约瑟夫问题(猴子选大王): n只猴子要选大王,选举办法如下:所有猴子按1,2,…,n编号围坐一圈,从第一号开始按1,2,…,m报数,凡报m号的推出圈外,如此循环报数,直到圈内剩下一只猴子时,这只猴子就是大王.n和m由键盘输入,打印出最后剩下的猴子号.
由于很多书上都有的习题,以及很多人问所以...
#include <stdio.h>
#include <malloc.h>
struct Link{
  int id;
  Link *next;
};
void Initialize(int n, Link *head)
{
  int i;
  Link *p;
  for (i = 1, p = head; i <= n; i++){
    p->next = (Link *) malloc (sizeof(Link));
    p = p->next;
    p->id = i;
  }
  p->next = head->next;
}

void Delete(Link *node)
{
  Link *temp;
  temp = node->next;
  printf("%d  ", node->next->id);
  node->next = temp->next;
  free(temp);
}
void main()
{
  Link *head, *p;
  int n, i, k;
  printf("%s","Input n,k = ");
  scanf("%d%d", &n, &k);
  head = (Link *) malloc (sizeof(Link));
  head->next = (Link *) malloc (sizeof(Link));
  Initialize(n, head);
  for (p = head, i = 1; p != p->next; p = p->next, i++){
    if (i == k){
      i = 1;
      Delete(p);
    }
  }
  printf(" n");
  printf("%d", p->id);
}
以下是一个堆排序和选择排序的效率对比的程序,随机生成20000个数据,一次只能选择一种排序算法的,最后一句输出程序运行的时间:
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
const int MAXSIZE = 20000;
const int N = 5;
int Data[MAXSIZE];
void Print()
{
  int i;
  for (i = 0; i < MAXSIZE; i++)
    printf ("%d ", Data[i]);
}
void Create()
{
  int i;
  randomize();
  for (i = 0; i < MAXSIZE; i++)
    Data[i] = random(1000);
  printf(" n");
}
void Swap(int *a, int *b)
{
  int temp;
  temp = *a;
  *a = *b;
  *b = temp;
}
void PushDown_MinHeap(int first, int last)
{
  long i, j, x;
  i = first;
  j = i * 2;
  x = Data[i];
  while (j <= last){
    if (j < last && Data[j] < Data[j+1])
      j++;
    if (x < Data[j]){
      Data[i] = Data[j];
      i = j;
      j = 2 * i;
    }
    else
      break;
  }
  Data[i] = x;
}
void MinHeapSort(int first, int last)
{
  int i;
  for (i = last / 2; i >= first; i--)
    PushDown_MinHeap(i, last);
  for (i = last; i > first; i--){
    Swap(&Data[first], &Data[i]);
    PushDown_MinHeap(first, i - 1);
  }
}

void Sort()
{
  int i, j;
  for (i = 0; i < MAXSIZE-1; i++)
    for (j = i; j < MAXSIZE; j++)
      if (Data[i] < Data[j])
 Swap(&Data[i], &Data[j]);
}
void main()
{
  struct time t1, t2;
  float t;
  printf ("%s n","---------------");
  Create();
  Print();
  gettime(&t1);
//  MinHeapSort(0, MAXSIZE-1);
  Sort();
  gettime(&t2);
  printf ("%s n","---------------");
//  Print();
  t = 60*(t2.ti_min-t1.ti_min)+(t2.ti_sec-t1.ti_sec)+1/100*(t2.ti_hund-t1.ti_hund);
  printf("running time is: %f n",t);
}

这个是快速,插入,选择排序的:
void Swap(int &i, int &j)
{
 int temp;
 temp = i;
 i = j;
 j = temp;
}
int Partition(int data[], int p, int r, int x)
{
 int i, j;
 i = p - 1;
 j = r + 1;
 while (1) {
  do j--; while (data[j] > x);
  do i++; while (data[i] < x);
  if (i < j)
   Swap(data[i], data[j]);
  else
   return j;
 }
}

void QuickSort(int data[], int p, int r)
{
 int q;
 if (p < r){
  q = Partition(data, p, r, data[p]);
  QuickSort(data, p, q);
  QuickSort(data, q+1, r);
 }
}


template <class T>
void Selection_Sort(T source[], T B[], int start, int last)
{
  int i, j, t;
  T temp;
  for (i = start; i < last-1; i++){
    t = i;
    for (j = i + 1; j < last; j++)
      if (source[t] > source[j])
        t = j;
    temp = source[t];
    source[t] = source[i];
    source[i] = temp;     //swap minimal element/ to source[i]
    B[i] = source[i];     //copy to B
  }
}

牛顿迭代法解方程的程序,公式是:X(i+1) = Xi - f(x)/f`(x) 用切线逼近:
#include <stdio.h>
#include <math.h>
float newton(int &a, int &b)
{
 const float eps = 1e-6;
 float x0 = 100, x = 0;
 float fx, flx;
 while (1){
  fx = a * x0 * x0 - b * x0 + 1;
  flx = 2 * a * x0 - b;
  x = x0 - fx / flx;
  if (fabs (x - x0) <= eps) break;
  else x0 = x;
 }
 return x;
}

void main()
{
 float x;
 int a0, a1;
 scanf ("%i %i", &a0, &a1);
 x = newton(a0, a1);
 printf ("%f n", x);
}

这里连带给出二分法求根思想,根x在(a,b)间,注意选正确的区间:
1)取a,b的中c=(a+b)/2,将根区间分两半,判断根在哪个区间。三种情况:
2)f(c) == 精度,C为求得根
3)if f(c)*f(a) < 0,求根区间在[a,c],b=c,转1)
4)if f(c)*f(a) > 0,求根区间在[c,b],a=c,转1)

该算法只能求出一个根,解3次方程适用.

稀疏矩阵的基本运算
问题:以“带行逻辑链接信息”的三元组顺序表表示稀疏矩阵,实现两 个矩阵相加、相减、相乘的运算。稀疏矩阵的输入形式采用三元组表示,而运算结果的矩阵则以通常 的阵列形式列出。
void TSMatrix_Add(TSMatrix A,TSMatrix B,TSMatrix &C)//三元组表示的稀疏矩阵加法
{
  C.mu=A.mu;C.nu=A.nu;C.tu=0;
  pa=1;pb=1;pc=1;
  for(x=1;x<=A.mu;x++) //对矩阵的每一行进行加法
  {
    while(A.data[pa].i<x) pa++;
    while(B.data[pb].i<x) pb++;
    while(A.data[pa].i==x&&B.data[pb].i==x)//行列值都相等的元素
    {
      if(A.data[pa].j==B.data[pb].j)
      {
        ce=A.data[pa].e+B.data[pb].e;
        if(ce) //和不为0
        {
          C.data[pc].i=x;
          C.data[pc].j=A.data[pa].j;
          C.data[pc].e=ce;
          pa++;pb++;pc++;
        }
      }//if
      else if(A.data[pa].j>B.data[pb].j)
      {
        C.data[pc].i=x;
        C.data[pc].j=B.data[pb].j;
        C.data[pc].e=B.data[pb].e;
        pb++;pc++;
      }
      else
      {
        C.data[pc].i=x;
        C.data[pc].j=A.data[pa].j;
        C.data[pc].e=A.data[pa].e
        pa++;pc++;
      }
    }//while
    while(A.data[pa]==x) //插入A中剩余的元素(第x行)
    {
      C.data[pc].i=x;
      C.data[pc].j=A.data[pa].j;
      C.data[pc].e=A.data[pa].e
      pa++;pc++;
    }
    while(B.data[pb]==x) //插入B中剩余的元素(第x行)
    {
      C.data[pc].i=x;
      C.data[pc].j=B.data[pb].j;
      C.data[pc].e=B.data[pb].e;
      pb++;pc++;
    }
  }//for
  C.tu=pc;
}//TSMatrix_Add

void TSMatrix_Minus(TSMatrix A,TSMatrix B,TSMatrix &C)//三元组表示的稀疏矩阵减法
{
  C.mu=A.mu;C.nu=A.nu;C.tu=0;
  pa=1;pb=1;pc=1;
  for(x=1;x<=A.mu;x++) //对矩阵的每一行进行减法
  {
    while(A.data[pa].i<x) pa++;
    while(B.data[pb].i<x) pb++;
    while(A.data[pa].i==x&&B.data[pb].i==x)//行列值都相等的元素
    {
      if(A.data[pa].j==B.data[pb].j)
      {
        ce=A.data[pa].e-B.data[pb].e;
        if(ce) //差不为0
        {
          C.data[pc].i=x;
          C.data[pc].j=A.data[pa].j;
          C.data[pc].e=ce;
          pa++;pb++;pc++;
        }
      }//if
      else if(A.data[pa].j>B.data[pb].j)
      {
        C.data[pc].i=x;
        C.data[pc].j=B.data[pb].j;
        C.data[pc].e=-B.data[pb].e;
        pb++;pc++;
      }
      else
      {
        C.data[pc].i=x;
        C.data[pc].j=A.data[pa].j;
        C.data[pc].e=A.data[pa].e
        pa++;pc++;
      }
    }//while
    while(A.data[pa]==x) //插入A中剩余的元素(第x行)
    {
      C.data[pc].i=x;
      C.data[pc].j=A.data[pa].j;
      C.data[pc].e=A.data[pa].e
      pa++;pc++;
    }
    while(B.data[pb]==x) //插入B中剩余的元素(第x行)
    {
      C.data[pc].i=x;
      C.data[pc].j=B.data[pb].j;
      C.data[pc].e=-B.data[pb].e;
      pb++;pc++;
    }
  }//for
  C.tu=pc;
}//TSMatrix_Minus

typedef struct
{
 int i,j;
 int e;
}Triple;

typedef struct
{
 Triple data[401];
 int rpos[21];
 int mu,nu,tu;
}RLSMatrix;

void TSMatrix_Mults(RLSMatrix A,RLSMatrix B,RLSMatrix &C)//三元组表示的稀疏矩阵乘法
{
 int arow,brow,ccol,tp,p,q,t;
 int ctemp[401];
 if(A.nu!=B.mu){Error=true;return;}
 C.mu=A.mu;C.nu=B.nu;C.tu=0;
 if(A.tu*B.tu!=0)
 {
  for(arow=1;arow<=A.mu;arow++)
  {
   memset(ctemp,0,sizeof(ctemp));
   C.rpos[arow]=C.tu+1;
   if(arow<A.mu)tp=A.rpos[arow+1];
   else{tp=A.tu+1;}
   for(p=A.rpos[arow];p<tp;++p)
   {
    brow=A.data[p].j;
    if(brow<B.mu)t=A.rpos[brow+1];
    else {t=B.tu+1;}
    for(q=B.rpos[brow];q<t;++q)
    {
     ccol=B.data[q].j;
     ctemp[ccol] += A.data[p].e*B.data[q].e;
    }
   }
   for(ccol=1;ccol<B.nu;++ccol)
    if(ctemp[ccol])
    {
     if(++C.tu>400)return;
     C.data[C.tu].i=arow;
     C.data[C.tu].j=ccol;
     C.data[C.tu].e=ctemp[ccol];
    }
  }
 }

}
几个比较好的算法和数据结构学习的网站
http://algorithm.lzu.edu.cn/
http://algorithm.myrice.com/
http://www.cpascal.com/
http://gz6hs.net/lzoi/index.html
http://www.itisonline.org/
http://218.5.5.86/drs/
http://202.109.195.141/chenyan/noi/noi.htm
http://www.periodicals.com.cn/qikan/index.j-sp
http://218.5.5.197/~drs/
http://www.bgy.gd.cn/gdoi/oszl/index.htm
http://noi.stedu.net/index0.asp
http://vip.6to23.com/dcyu/ //dcyu的主页 :)
http://www.cfcs.com.cn/fjas/index.htm  //信息学的好站点,有很多学习资源
http://www.cfcs.com.cn/fjas/index.htm  //福建信息学奥赛站点,内容还不多:)

Kruskal最小生成树算法: http://vip.6to23.com/dcyu/TurboC/algorithm/4.html
马的遍历问题: http://vip.6to23.com/dcyu/TurboC/algorithm/7.html
最大子矩阵问题: http://vip.6to23.com/dcyu/TurboC/algorithm/8.html
A*算法的8数码问题原码: http://vip.6to23.com/dcyu/csdn/expert/1167422.xml
计算圆周率PI的算法: http://vip.6to23.com/dcyu/csdn/Algorithm/1068477.xml
二分图的最大匹配问题: http://vip.6to23.com/dcyu/csdn/expert/1082332.xml
线性拟合的简单高效算法:http://vip.6to23.com/dcyu/csdn/Algorithm/988306.xml
n皇后的求法:http://vip.6to23.com/dcyu/csdn/expert/911952.xml
自然数n的拆分数:http://search.csdn.net/expert/topic/6/603/2002/5/24/750682.htm
生成全排列的算法:http://vip.6to23.com/dcyu/csdn/expert/843002.xml