找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 2442|回复: 1

为什么写循环时要把小循环作为外侧循环?

[复制链接]

307

主题

228

回帖

7349

积分

用户组: 真·技术宅

UID
2
精华
76
威望
291 点
宅币
5599 个
贡献
253 次
宅之契约
0 份
在线时间
949 小时
注册时间
2014-1-25
发表于 2014-7-19 22:10:25 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
我们总是说,为了提高程序效率,再遇到多重循环时,应该吧小循环作为外侧循环而大循环作为内测循环,这个是为什么呢?
下面是个简单的矩阵加法例子:

  1. Void Addm(T** a,...)
  2. {
  3.         for(int i=0;i<rows;i++)
  4.                 for(int j=0;j<cols;j++)
  5.                         c[i][j]=a[i][j]+b[i][j];
  6.        
  7. }
复制代码


语句s/e 频率 总步数
Void Addm(T** a,...)  0 0 0
{ 0 0 0
  for(int i=0;i<rows;i++) 1 rows+1 rows+1
    for(int j=0;j<cols;j++)1 rows*(cols+1) rows*cols+rows
      c[i ][j]=a[i ][j]+b[i ][j]1 rows*cols rows*cols
} 0 0 0
总计 2*rows*cols+2*rows+1


(以下++、赋值、判断均看做单位时间操作)
for(int i=0;i<rows;i++)       
这一句从i=0 i=1 ... 直到i=rows判断出界才终止,因此对i的操作次数为rows+1次
for(int j=0;j<cols;j++)
这一句由于上面i的循环体实际循环了rows次,而j的操作次数类似于上一句为cols+1次,因此总共为rows*(cols+1)次
循环体中循环次数由上面可以看出来循环体循环了rows*cols次,因此c[i ][j]这句步数是rows*cols
和为:2*rows*cols+2*rows+1
因此当外循环次数较大,即rows远大于cols,其步数将会远大于将次数较多的循环放到内存的的步数,得证
回复

使用道具 举报

307

主题

228

回帖

7349

积分

用户组: 真·技术宅

UID
2
精华
76
威望
291 点
宅币
5599 个
贡献
253 次
宅之契约
0 份
在线时间
949 小时
注册时间
2014-1-25
 楼主| 发表于 2014-7-28 23:23:15 | 显示全部楼层
算法笔记-寻找第N小元素:
  1. 设数组大小为SIZE
  2. 如果N=SIZE/2 则为求中位数的问题,如果N=0或SIZE-1则为求最值问题

  3. // findth.cpp : Defines the entry point for the console application.
  4. //

  5. #include "stdafx.h"
  6. #include <stdio.h>
  7. #include <stdlib.h>

  8. int main(int argc, char* argv[])
  9. {
  10. const int size=7;
  11. int data[size];
  12. for(int i=0;i<size;i++)
  13. {
  14.   data[i]=rand()&0xFF;
  15.   printf("%d\n",data[i]);
  16. }
  17. printf("\n");

  18. for(int tofindindex=0;tofindindex<size;tofindindex++)
  19. {
  20.   int begin=0,end=size-1;

  21.   while(true)
  22.   {
  23.    int tmp=data[begin];
  24.    int begin1=begin,end1=end;
  25.    while(begin1 < end1)
  26.    {
  27.     while(begin1 < end1 && data[end1] >= tmp)
  28.      end1--;
  29.     data[begin1]=data[end1];
  30.     while(begin1 < end1 && data[begin1] <= tmp)
  31.      begin1++;
  32.     data[end1]=data[begin1];
  33.    }
  34.    data[begin1]=tmp;
  35.    
  36.    if(tofindindex > begin1)
  37.    {
  38.     begin=begin1+1;
  39.    }
  40.    else if(tofindindex < begin1)
  41.    {
  42.     end=begin1-1;
  43.    }
  44.    else
  45.    {
  46.     printf("The %dth is %d\n",tofindindex,data[tofindindex]);
  47.     break;
  48.    }
  49.   }
  50. }

  51. getchar();
  52. }

  53. // 41
  54. // 35
  55. // 190
  56. // 132
  57. // 225
  58. // 108
  59. // 214
  60. //
  61. // The 0th is 35
  62. // The 1th is 41
  63. // The 2th is 108
  64. // The 3th is 132
  65. // The 4th is 190
  66. // The 5th is 214
  67. // The 6th is 225
复制代码






贪心算法:
  1. procedure GREEDY(A,n)
  2.     solution<-∅
  3.     for i<-1 to n do
  4.         x<-SELECT(A)
  5.         if FEASIBLE(solution,x)
  6.         then solutions<-UNION(solution,x)
  7.         endif
  8.     repeat
  9.     return(solution)
  10. end GREEDY

  11. 选择能产生问题最优解的最有亮度标准是使用贪心发设计求解的核心问题

  12. 背包问题:
  13.     p1/w1>=p2/w2>=...>=pn/wn
  14. procedure KNAPSACK(P,W,M,X,n)
  15.     P(i)/W(i)>=P(i+1)/W(i+1)
  16.     real P(1:n),W(1:n),X(1:n),M,cu;
  17.     integer i,n;
  18.     X<-0
  19.     cu<-M
  20.     for i<-1 to n do
  21.         if W(i)>cu then exit endif
  22.         X(i)<-1
  23.         cu<-cu-W(i)
  24.     repeat
  25.     if i<=n then X(i)<-cu/W(i)
  26.     endif
  27. end KNAPSACK

复制代码



分治法:

  1. 二分检索算法:A[1:n]有序
  2. procedure BINSRCH(A,n,x,j)
  3. //查找x,如果找到则用j设置
  4.     integer low,high,mid,j,n;
  5.     low<-1;high<-n
  6.     while low<=high do
  7.         mid<-[low+high]/2
  8.         case
  9.              x<A(mid):high<-mid-1
  10.              x>A(mid):low<-mid+1
  11.    else:j<-mid:return
  12. endcase
  13.     repeat
  14.     j<-0
  15. end BINSRCH

  16. 找最大和最小元素
  17. procedure MAXMIN(i,j,fmax,fmin)
  18. //fmax fmin存放最大和最小元素
  19.     integer i,j;global n,A(1:n)
  20.     case
  21.         i=j:fmax<-fmin<-A(i)//只有一个元素
  22.         i=j-1;if A(i)<A(j) then fmax<-A(j);fmin<-A(i)//有2个元素
  23.                  else fmax<-A(i);fmin<-A(j)
  24.                  endif
  25.         else
  26.             mid<-[i+j]/2
  27.             call MAXMIN(i,mid,max1,min1)
  28.             call MAXMIN(mid+1,j,max2,min2)
  29.             fmax<-max(max1,max2)
  30.             fmin<-min(min1,min2)
  31.     endcase
  32. end MAXMIN

  33. 复杂度:
  34. T(0)=0
  35. T(1)=1
  36. T(n)=2*T(n/2)+2=3n/2-2 好于直接比较的2n-2

  37. 归并排序:
  38. procedure MERGESORT(low,high)
  39.     integer low,high;
  40.     if low<high then
  41.         mid<-n/2
  42.         call MERGESORT(low,mid)
  43.         call MERGESORT(mid+1,high)
  44.         call MERGE(low,mid,high)
  45.     endif
  46. end MERGESORT

  47. procedure MERGE(low,mid,high)
  48.     integer h,i,j,k;
  49.     h<-low;i<-low;j<-mid+1
  50.     while h<=mid and j<=high do
  51.         if A(h)<=A(j) then B(i)<-A(h);h<-h+1
  52.         else B(i)<-A(j);j<-j+1
  53.         endif
  54.         i<-i+1
  55.     repeat
  56.     if h>mid then
  57.         for k<-j to high do
  58.             B(i)<-A(k);i<-i+1
  59.         repeat
  60.     else
  61.         for k<-h to mid do
  62.             B(i)<-A(k);i<-i+1
  63.         repeat
  64.     endif
  65. end MERGE

  66.         复杂度:
  67.         T(1)=a
  68.         T(n)=2T(n/2)+cn=2^k*T(1)+kcn;=O(nlogn)

  69. 快速排序:
  70.     快速分类:吧小于某元素和大于某元素的元素移动到2边
  71. procedure QuickSort(p,q)
  72.     int p,q;global n,A[1:n]
  73.     if p<q then
  74.         j=q+1;Partition(p,j)
  75.         QuickSort(p,j-1);
  76.         QuickSort(j+1,q);
  77.     endif
  78. end QuickSort

  79. procedure PARTITION(m,p)
  80.     integer m,p,i;global A(m:p-1)
  81.     v<-A(m);i<-m
  82.     loop
  83.         loop i<-i+1 until A(i)>=v repeat
  84.         loop p<-p-1 until A(p)<=v repeat
  85.         if i<p
  86.             then call INTERCHANGE(A(i),A(p))
  87.             else exit
  88.         endif
  89.     repeat
  90.     A(m)<-A(P)
  91. End PARTITION

  92.         复杂度:
  93.         最坏情况下O(n^2),平均O(nlogn)

复制代码



满二叉树:
    深度为k且有2^k-1个节点的二叉树称为满二叉树。
    编号从根节点起,自上而下自左向右。
完全二叉树:
    深度为k且有n个节点的二叉树,当且仅当每一个节点都与深度为k的满二叉树中编号从1至n的节点一一对应的二叉树称为完全二叉树

    节点个数=分支个数+1
    所有节点度之和=2*边数

多项式合并:
  1. 多项式合并代码:
  2. // test.cpp : Defines the entry point for the console application.
  3. //

  4. #include "stdafx.h"

  5. #include <stdio.h>
  6. #include <malloc.h>

  7. struct ElemType
  8. {
  9. ElemType* next;
  10. float coef;//系数
  11. int expn;//指数
  12. };

  13. ElemType* head1=NULL;
  14. ElemType* head2=NULL;

  15. ElemType* CreatePolyn()
  16. {//初始化多项式
  17. ElemType* head=(ElemType*)malloc(sizeof(ElemType));
  18. head->next=NULL;
  19. return head;
  20. }

  21. void AddPolyn(ElemType* head,float coef,int expn)
  22. {//增加多项式节点
  23. if(coef == 0.0)
  24.   return;
  25. for(ElemType* cur=head;cur->next != NULL && cur->next->expn < expn;cur=cur->next);
  26. ElemType* newnode=(ElemType*)malloc(sizeof(ElemType));
  27. newnode->next=cur->next;
  28. newnode->coef=coef;
  29. newnode->expn=expn;
  30. cur->next=newnode;
  31. }

  32. void PrintPolyn(ElemType* head)
  33. {//打印多项式
  34. for(ElemType* cur=head->next;cur != NULL;cur=cur->next)
  35. {
  36.   printf("coef:%f,expn=%d\n",cur->coef,cur->expn);
  37. }
  38. }

  39. void MergePolyn(ElemType* head1,ElemType* head2)
  40. {//合并多项式head1+head2->head1
  41. ElemType* cur1=head1;

  42. while(cur1->next && head2->next)
  43. {
  44.   ElemType* cur2=head2->next;

  45.   if(cur2->expn < cur1->next->expn)//插入cur1之前
  46.   {
  47.    head2->next=cur2->next;
  48.    cur2->next=cur1->next;
  49.    cur1->next=cur2;
  50.   }
  51.   else if(cur2->expn == cur1->next->expn)
  52.   {
  53.    cur1->next->coef += cur2->coef;
  54.    
  55.    if(cur1->next->coef == 0)
  56.    {
  57.     ElemType* p=cur1->next;
  58.     cur1->next=p->next;
  59.     delete p;
  60.    }
  61.    else
  62.    {
  63.     cur1=cur1->next;
  64.    }
  65.    head2->next=cur2->next;
  66.    delete cur2;
  67.   }
  68.   else
  69.   {
  70.    cur1=cur1->next;
  71.   }

  72. }

  73. if(head2->next)
  74.   cur1->next=head2->next;
  75. head2->next=NULL;
  76. }

  77. void DestroyPolyn(ElemType* head)
  78. {//销毁多项式
  79. ElemType* cur=head;
  80. while(cur->next)
  81. {
  82.   ElemType* p=cur->next;
  83.   delete cur;
  84.   cur=p;
  85. }
  86. }

  87. int main(int argc, char* argv[])
  88. {
  89. head1=CreatePolyn();
  90. head2=CreatePolyn();
  91. //7+3x+9x^8+5x^17
  92. AddPolyn(head1,7,0);
  93. AddPolyn(head1,3,1);
  94. AddPolyn(head1,9,8);
  95. AddPolyn(head1,5,17);
  96. printf("head1:\n");
  97. PrintPolyn(head1);

  98. //8x+22x^7-9x^8
  99. AddPolyn(head2,8,1);
  100. AddPolyn(head2,22,7);
  101. AddPolyn(head2,-9,8);
  102. printf("head2:\n");
  103. PrintPolyn(head2);

  104. MergePolyn(head1,head2);
  105. printf("head1:\n");
  106. PrintPolyn(head1);
  107. printf("head2:\n");
  108. PrintPolyn(head2);
  109. DestroyPolyn(head1);
  110. DestroyPolyn(head2);

  111. getchar();
  112. return 0;
  113. }
复制代码



  1. 单链表头结点移动到链表最后:
  2.     Status A(LinList L)
  3.     {
  4.         if(L && L->next)   
  5.         {
  6.             Q=L;
  7.             L=L->next;
  8.             P=L;
  9.             while(P->next) P=P->next;
  10.             P->next=Q;
  11.             Q->next=NULL;
  12.         }
  13.         return OK;
  14.     }

  15. 双链表拆分成2个双链表
  16.     void BB(LNode* s,LNode* q)
  17.     {
  18.         p=s;
  19.         while(p->next != q)
  20.             p=p->next;
  21.         p->next=s;
  22.     }

  23.     void AA(LNode* pa,LNode* pb)
  24.     {
  25.         BB(pa,pb);
  26.         BB(pb,pa);
  27.     }

  28. 10进制转换为8进制
  29.     void conversion()
  30.     {
  31.         InitStack(S);
  32.         scanf("%d",N);
  33.         while(N)
  34.         {
  35.             Push(S,N%8);
  36.             N=N/8;
  37.         }
  38.         while(!StackEmpty(s))
  39.         {
  40.             Pop(S,e);
  41.             printf("%d",e);
  42.         }
  43.     }
复制代码
回复 赞! 靠!

使用道具 举报

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-5-5 15:29 , Processed in 0.039199 second(s), 30 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表