Jason ---分享,共同进步

激情成就梦想,努力创造未来
随笔 - 53, 文章 - 1, 评论 - 45, 引用 - 0
数据加载中……

数据结构与算法(1)


一,概述

许多将要讨论到的算法直接适用于某些特殊的数据结构。对于大多数数据结构来说,都需要知道如何

插入一条新的数据
寻找某一条特定的数据项
删除某一特定的数据项

1,数据结构的特征:

数据结构    优点                                   缺点

数组     插入快,如果有下标,可以非常快的存取   查找慢,删除慢,大小固定

有序数组    比无序的数组查找快                     删除和插入慢,大小固定

栈        提供后进先出方式的存取                 存取其他项很慢

队列       提供先进先出方式的存取        存取其他项很慢

链表     插入快,删除快                         查找慢

二叉树      查找,插入,删除都快(如果树保持平衡) 删除算法复杂

红-黑树     查找,插入,删除都快。数总是平衡的    算法复杂

2-3-4 树    查找,插入,删除都快。树总是平衡的     算法复杂
            类似的树对磁盘存储有用。 

哈希表      如果关键字已知则存取极快。插入快       删除慢,如果不知道关键字则存取很慢,对
         存储空间是用不充分。

堆     插入,删除快,对最大数据项的存取很快   对其他数据项存取很慢

图     对现实世界建模      有些算法慢且复杂

二 ,数组

数组是应用最广泛的数据存储结构。他被植入到大部分编成语言中,由于数组十分易懂,所以它被用来作为介绍数据结构的起步点,并展示面向对象编程的数据结构之间的相互关系。


使用二分法可以大大提高检索速度,减少查询次数。

二分法所需要的比较次数

范围                    次数

10   4
100   7
1000   10
10000   14
100000   17
1000000   20
10000000  24
100000000  27
1000000000  30


根据上面的二分法查询次数,我们还可以推断出来一个方程式:
r = 2*2....s;(s表示步数(次数),乘2的次数,即2的幂), r表示范围。
例如:如果是已知步数s,通过这个方程就可以得出范围r,如: 如果s是6,则范围应该是64;

同样可以根据对数来计算其相应的次数.

大O表示法:
在计算机算法中,我们使用一种粗略的度量算法效率的方法称作"大O"表示法.
在比较算法时似乎应该说一些类似"算法A比算法B快两倍"之类的话,但实际上这些陈述并没有多大意义。这是由于当数据项个数变化时,对应的比例也会发生根本改变。

用大O表示法表示运行时间

算法                              大O表示法表示的运行时间

线性查找    O(N)
二分查找    O(logN)
无序数组的插入    O(1)
有序数组的插入    O(N)
无序数组的删除    O(N)
有序数组的删除    O(N)

上面的显示了时间与数据项个数的大O关系。通过它我们可以比较不同的大O值(非常主观)
:O(1)是优秀,O(logN)是良好, O(N) 还可以,O(N的平方)则差了一些。


三,简单排序

一旦建立了一个重要的数据库后,就可能根据某些需求对数据进行不同方式排序.比如对姓名按字母序排序,对学生按年级排序,对顾客按邮政编码排序,对国内销售品按价格排序,等.
   对数据进行排序有可能是检索的一个初始步骤.正如在第二章"数组"中看到的那样,二分查找法比线性查找法要快的多,然而它只能应用于有序的数据.
   冒泡排序
冒泡排序算法运行起来非常慢,但在概念上他是排序算法中最健的,因此冒泡排序算法在刚开始研究排序技术时是一个非常好的算法.
冒泡算法要遵循的规则(一组数按照从小到大的顺序排序 从左到右)

1,比较两个数.
2,如果左边的值大,则两个数交换位置(如果左边的值不大那么不改变位置) .
3,向右移动一个位置,比较下面两个数.
这样一直比下去,一直比到最右端,那么最大的数就可以比较出来了.

冒泡排序的java代码:

package sort;
/**
 * 冒泡排序
 * 
@author jason
 *
 
*/

public class BubbleSort
   
{
   
public static void main(String[] args)
      
{
      
int maxSize = 100;            // array size
      ArrayBub arr;                 // reference to array
      arr = new ArrayBub(maxSize);  // create the array

      arr.insert(
77);               // insert 10 items
      arr.insert(99);
      arr.insert(
44);
      arr.insert(
55);
      arr.insert(
22);
      arr.insert(
88);
      arr.insert(
11);
      arr.insert(
00);
      arr.insert(
66);
      arr.insert(
33);

      arr.display();                
// display items

      arr.bubbleSort();             
// bubble sort them

      arr.display();                
// display them again
      }
  // end main()
   }

 
class ArrayBub {
    
       
private long[] a;                 // ref to array a
       private int nElems;               // number of data items
//    --------------------------------------------------------------
       public ArrayBub(int max)          // constructor
          {
          a 
= new long[max];                 // create the array
          nElems = 0;                        // no items yet
          }

//    --------------------------------------------------------------
       public void insert(long value)    // put element into array
          {
          a[nElems] 
= value;             // insert it
          nElems++;                      // increment size
          }

//    --------------------------------------------------------------
       public void display()             // displays array contents
          {
          
for(int j=0; j<nElems; j++)       // for each element,
             System.out.print(a[j] + " ");  // display it
          System.out.println("");
          }

//    --------------------------------------------------------------
       public void bubbleSort()
          
{
          
int out, in;

          
for(out=nElems-1; out>1; out--)   // outer loop (backward)
             for(in=0; in<out; in++)        // inner loop (forward)
                if( a[in] > a[in+1] )       // out of order?
                   swap(in, in+1);          // swap them
          }
  // end bubbleSort()
//    --------------------------------------------------------------
       private void swap(int one, int two)
          
{
          
long temp = a[one];
          a[one] 
= a[two];
          a[two] 
= temp;
          }

//    --------------------------------------------------------------
       }
  // end class ArrayBub

上面的代码中为了清晰起见,使用了一个独立的swap()方法来执行交换操作,实际上使用一个独立的swap()方法不一定好,因为方法调用会增加一些额外的消耗.最好还是将交换方法直接放到程序中,这样可以提高一些速度.
通过上面的程序,我们可以看到,比较执行的次数
为: 9+8+7+6+5+4+3+2+1=45
公式为: N*(N-1)/2
因为两个数值只有在需要时才交换,所以交换的次数少于比较的次数.如果数据是随机的那么大概有一半数据需要交换.
冒泡排序运行需要时间可以认为:O(N平方)这个级别算法速度很慢。


选择排序:

选择排序改进了冒泡排序,将交换次数从O(N平方)减少到O(N),但是比较次数仍为 O(N平方).然而,选择排序仍然为大记录的排序提出一个非常重要的改进,因为这些大量的记录需要在内存中移动,这就是交换的时间和比较时间相比起来,交换时间更为重要.(一般来说,在java语言中不是这种情况,java中只是改变引用位置,而实际对象的位置并没有发生改变.)

选择算法要遵循的规则(一组数按照从小到大的顺序排序 从左到右)

1,从当前所有数中选择一个最小的 ,放在第一位(换位),然后从第二个开始同样选择最小的.
开始向右移动,选择对小的放在第二位,以此这样操作。
就可以得到排序的效果。

选择排序的程序代码 :

package sort;
/**
 * 选择排序
 * 
@author jason
 *
 
*/

public class BubbleSort
   
{
   
public static void main(String[] args)
      
{
      
int maxSize = 100;            // array size
      ArrayBub arr;                 // reference to array
      arr = new ArrayBub(maxSize);  // create the array

      arr.insert(
77);               // insert 10 items
      arr.insert(99);
      arr.insert(
44);
      arr.insert(
55);
      arr.insert(
22);
      arr.insert(
88);
      arr.insert(
11);
      arr.insert(
00);
      arr.insert(
66);
      arr.insert(
33);

      arr.display();                
// display items

      arr.bubbleSort();             
// bubble sort them

      arr.display();                
// display them again
      }
  // end main()
   }

 
class ArrayBub {
    
       
private long[] a;                 // ref to array a
       private int nElems;               // number of data items
//    --------------------------------------------------------------
       public ArrayBub(int max)          // constructor
          {
          a 
= new long[max];                 // create the array
          nElems = 0;                        // no items yet
          }

//    --------------------------------------------------------------
       public void insert(long value)    // put element into array
          {
          a[nElems] 
= value;             // insert it
          nElems++;                      // increment size
          }

//    --------------------------------------------------------------
       public void display()             // displays array contents
          {
          
for(int j=0; j<nElems; j++)       // for each element,
             System.out.print(a[j] + " ");  // display it
          System.out.println("");
          }

//    --------------------------------------------------------------
       public void bubbleSort()
          
{
          
int out, in;

          
for(out=nElems-1; out>1; out--)   // outer loop (backward)
             for(in=0; in<out; in++)        // inner loop (forward)
                if( a[in] > a[in+1] )       // out of order?
                   swap(in, in+1);          // swap them
          }
  // end bubbleSort()
//    --------------------------------------------------------------
       private void swap(int one, int two)
          
{
          
long temp = a[one];
          a[one] 
= a[two];
          a[two] 
= temp;
          }

//    --------------------------------------------------------------
       }
  // end class ArrayBub


插入排序

在大多数情况下,插入排序是比上面两种排序算法要好的一种,虽然算法仍然要O(N平方)的时间,但在一般情况下,它要比冒泡排序快一倍,比选择排序还要快一点。尽管它比冒泡排序算法和选择算法都更麻烦一些,但它也并不很复杂。他经常被用在较复杂的排序算法的最后阶段,例如快速排序。


插入算法原理:
插入算法要遵循的规则(一组数按照从小到大的顺序排序 从左到右)

插入排序,从第一位开始,如果第二位小于第一位,那么第一位和第二位换位,第一位与第二位有正确的顺序,
这时排序好的第二位与第三位比较,如果第三位小于第二位,那么拿出第三位的值,并且把第二位移到第三位上,
然后比较这个临时值(原来的第三位)与第一位比较,如果第一位也大于第三位,那么同样,第一位移到原来第二位的位置
这个临时值就占据了第一位,如果一位的值小于临时值(原来的第三位),则第一位不变,第二位为临时值,以此类推
就是插入算法的原理.

插入算法就是对一个有序的序列,进行插入操作.

插入排序代码:

package sort;
/**
 * 
 * 
@author jason
 *
 
*/

class ArrayIns
{
private long[] a;                 // ref to array a
private int nElems;               // number of data items
//--------------------------------------------------------------
public ArrayIns(int max)          // constructor
   {
   a 
= new long[max];                 // create the array
   nElems = 0;                        // no items yet
   }

//--------------------------------------------------------------
public void insert(long value)    // put element into array
   {
   a[nElems] 
= value;             // insert it
   nElems++;                      // increment size
   }

//--------------------------------------------------------------
public void display()             // displays array contents
   {
   
for(int j=0; j<nElems; j++)       // for each element,
      System.out.print(a[j] + " ");  // display it
   System.out.println("");
   }

//--------------------------------------------------------------
public void insertionSort()
   
{
   
int in, out;

   
for(out=1; out<nElems; out++)     // out is dividing line
      {
      
long temp = a[out];            // remove marked item
      in = out;                      // start shifts at out
      while(in>0 && a[in-1>= temp) // until one is smaller,
         {
         a[in] 
= a[in-1];            // shift item to right
         --in;                       // go left one position
         }

      a[in] 
= temp;                  // insert marked item
      }
  // end for
   }
  // end insertionSort()
//--------------------------------------------------------------
}
  // end class ArrayIns
////////////////////////////////////////////////////////////////
class InsertSortApp
{
public static void main(String[] args)
   
{
   
int maxSize = 100;            // array size
   ArrayIns arr;                 // reference to array
   arr = new ArrayIns(maxSize);  // create the array

   arr.insert(
77);               // insert 10 items
   arr.insert(99);
   arr.insert(
44);
   arr.insert(
55);
   arr.insert(
22);
   arr.insert(
88);
   arr.insert(
11);
   arr.insert(
00);
   arr.insert(
66);
   arr.insert(
33);

   arr.display();                
// display items

   arr.insertionSort();          
// insertion-sort them

   arr.display();                
// display them again
   }
  // end main()
}
  // end class InsertSortApp

posted on 2008-08-01 12:02 agun 阅读(339) 评论(2)  编辑  收藏 所属分类: 数据结构与算法

评论

# re: 数据结构与算法(1)  回复  更多评论   

很好的,学习一下。
2008-09-03 11:20 | A8

# re: 数据结构与算法(1)  回复  更多评论   

呵呵,互相学习,多上来交流。
2008-09-03 11:21 | agun

只有注册用户登录后才能发表评论。


网站导航: