??xml version="1.0" encoding="utf-8" standalone="yes"?> q里Q我们简单介l几U排序方法,直接插入排序、希儿排序、冒泡排序、快速排序、直接选择排序Q文中所提及的代码在IE6下测试通过?/p>
直接插入排序基本思想
法描述
希尔排序基本思想 法描述
冒排序基本思想 法描述
快速排序基本思想 法描述 在本机浏览器中对的表格数据进行排?br />在Web应用中,数据从服务器端返回到客户端,以表格Ş式表现出来。如果要Ҏ据集按指定的列排序显C,常规做法都是向服务器发出hQ服务器端程序重C数据库中取出按指定列排序的数据,q回l客LQ页面重新显C排序后数据?br />
假设待排序的记录存放在数lR[1..n]中。初始时QR[1]自成1个有序区Q无序区为R[2..n]。从i=2L至i=n为止Q依ơ将R[i]插入当前的有序区R[1..i-1]中,生成含n个记录的有序区?/p>
var st = new Date();
var temp, j;
for(var i=1; i<arr.length; i++) {
if((arr[i]) < (arr[i-1])) {
temp = arr[i];
j = i-1;
do {
arr[j+1] = arr[j];
j--;
}
while (j>-1 && (temp) < (arr[j]));
arr[j+1] = temp;
}//endif
}
status = (new Date() - st) + ' ms';
return arr;
}
先取一个小于n的整数d1作ؓW一个增量,把文件的全部记录分成d1个组。所有距Mؓdl的倍数的记录放在同一个组中。先在各l内q行直接插h排序Q然后,取第二个增量d2<d1重复上述的分l和排序Q直x取的增量dt=1(dt<dt-l<?lt;d2<d1)Q即所有记录放在同一l中q行直接插入排序为止?br /> 该方法实质上是一U分l插入方法?/p>
var st = new Date();
var increment = arr.length;
do {
increment = (increment/3|0) + 1;
arr = ShellPass(arr, increment);
}
while (increment > 1)
status = (new Date() - st) + ' ms';
return arr;
}
function ShellPass(arr, d) { //希儿排序分段执行函数
var temp, j;
for(var i=d; i<arr.length; i++) {
if((arr[i]) < (arr[i-d])) {
temp = arr[i]; j = i-d;
do {
arr[j+d] = arr[j];
j = j-d;
}
while (j>-1 && (temp) < (arr[j]));
arr[j+d] = temp;
}//endif
}
return arr;
}
被排序的记录数lR[1..n]垂直排列Q每个记录R[i]看作是重量ؓR[i].key的气泡。根据轻气不能在重气之下的原则,从下往上扫描数l?
RQ凡扫描到违反本原则的轻气Q就使其向上"飘Q"。如此反复进行,直到最后Q何两个气泡都是轻者在上,重者在下ؓ止?br />
var st = new Date();
var temp;
var exchange;
for(var i=0; i<arr.length; i++) {
exchange = false;
for(var j=arr.length-2; j>=i; j--) {
if((arr[j+1]) < (arr[j])) {
temp = arr[j+1];
arr[j+1] = arr[j];
arr[j] = temp;
exchange = true;
}
}
if(!exchange) break;
}
status = (new Date() - st) + ' ms';
return arr;
}
原问题分解q个规模更小但结构与原问题相似的子问题。递归地解q些子问题,然后这些子问题的解l合为原问题的解?br />
在R[low..high]中Q选一个记录作为基?Pivot)Q以此基准将当前无序区划分ؓ左、右两个较小的子区间R[low..pivotpos-
1)和R[pivotpos+1..high]Qƈ使左边子区间中所有记录的关键字均于{于基准记录(不妨Cؓpivot)的关键字
pivot.keyQ右边的子区间中所有记录的关键字均大于{于pivot.keyQ而基准记录pivot则位于正的位置(pivotpos)上,它无
d加后l的排序?/p>
if (arguments.length>1) {
var low = arguments[1];
var high = arguments[2];
} else {
var low = 0;
var high = arr.length-1;
}
if(low < high){
// function Partition
var i = low;
var j = high;
var pivot = arr[i];
while(i<j) {
while(i<j && arr[j]>=pivot)
j--;
if(i<j)
arr[i++] = arr[j];
while(i<j && arr[i]<=pivot)
i++;
if(i<j)
arr[j--] = arr[i];
}//endwhile
arr[i] = pivot;
// end function
var pivotpos = i; //Partition(arrQlowQhigh);
QuickSort(arr, low, pivotpos-1);
QuickSort(arr, pivotpos+1, high);
} else
return;
return arr;
}
直接选择排序基本思想
n个记录的文g的直接选择排序可经qn-1直接选择排序得到有序l果Q?br /> ①初始状态:无序ZؓR[1..n]Q有序区为空?br /> ②第1排?br /> 在无序区R[1..n]中选出关键字最的记录R[k]Q将它与无序区的W?个记录R[1]交换QR[1..1]和R[2..n]分别变ؓ记录个数增加1个的新有序区和记录个数减?个的新无序区?br /> …?br /> ③第i排?br /> Wi排序开始时Q当前有序区和无序区分别为R[1..i-1]和R[i..n](1≤i≤n-1)。该排序从当前无序Z选出关键字最的记录R [k]Q将它与无序区的W?个记录R[i]交换QR[1..i]和R[i+1..n]分别变ؓ记录个数增加1个的新有序区和记录个数减?个的新无序区?br /> q样Qn个记录的文g的直接选择排序可经qn-1直接选择排序得到有序l果?br />
法描述
function SelectSort(arr) { //选择排序->直接选择排序
var st = new Date();
var temp;
for(var i=0; i<arr.length; i++) {
var k = i;
for(var j=i+1; j<arr.length; j++) {
if((arr[j]) < (arr[k]))
k = j;
}
if (k != i){
temp = arr[i];
arr[i] = arr[k];
arr[k] = temp;
}
}
status = (new Date() - st) + ' ms';
return arr;
}
采用q种方式有如下缺点:
1- 响应旉延迟Q每ơ排序都要向服务器端发送请求,{待l果q回Q同时增加网l负载?br />2- ~程复杂Q可l护性差Q而且客户端和服务器端代码耦合度很高,客户端和服务器端都要处理排序涉及的列名、排序方式,如果有分和查询条gQ都需要在客户端页面中保留Q排序请求时重新传递到服务器端Q当参数数量很多时极易出错?br />3- 重用度很低,针对不同表格Q很难抽象出一个公q序来qQ需要逐个~写代码实现Q增加工作量?br />
现在换一个角度考虑Q数据既然已下蝲C客户端,在重新排序时没有必要再重服务器端获取Q只要对览器中的数据重新排序显C就可以了。要实现该目标,需要做C下几点:
1 - 获得表格中要排序的数据,其攑օ一?l数l中?br />2 - ?l数l排序?br />3 - 用排序后的数据重新更新表根{?br />
利用览器支持的DOM(Document Object Model)和JavaScript卛_实现上述目标?br />
通常面中会很多?lt;table>Q要获得需要排序数据所在的tableQ需要在<table>中增加一个id属性,便于document对象用getElementById得到该表格对象,例如要排序的表格定义如下Q?br /> <table id="st" >
<tr>
<td>1</td>
<td>2</td>
</tr>
</table>
在javascript中,用var objTable = document.getElementById("st")可得到表格对象Q该对象在DOM中定义ؓ一个Element?br />
?
后用 var objRows =
objTable.getElementsByTagName("tr")得到该表g全部的行对象QObjRows.lengthq回该表D敎ͼ
var rowi =
objRows[i].getElementsByTagName("td")得到Wi行的全部<td>节点Qi?开始计敎ͼ
rowi.item(j)则可得到Wi行,Wj列的节点Q该节点的innerHTML节点<td></td>之间的内宏V?br />
获取表格数据?l数l的代码见源代码Q此处略?br />
下面说明在javascript?l数l的构造和排序?br />javascript不支?l数l,因此需要用数组的数l来模拟一?l数l,其方法是先定义一?l数l,元素个数?l数l的行数Q然后对每个元素赋一个|gؓ一个数l,其元素个Cؓ2l数l的列数。构造代码如下:
var rows = new Array(R); //R?br />for(var i = 0; i < rows.length; i++){
rows[i] = new Array(C); //C为列?br />}
利用javascript中的Array.sort(comparer)对rows中的元素排序Q比较方式由重新定义的比较函数得到。要ҎWj列元素的大小排序Q只要定义如下函数即可:
function compareCol(a,b){
if (a[j] < b[j])
return -1;
if (a[j] > b[j])
return 1;
return 0;
}
因ؓcompareCol只能有两个参敎ͼ因此j要定义ؓ全局变量?br />
用rows.sort
(compareCol)可实现Ҏj列值的大小对行q行排序。根据javascript文档Q字W串比较大小是按照其Unicode~码的大来?
较,对英文排序没有问题,对中文排序时׃是按通常的拼x序,那需要javascript提供本地化支持,目前没有发现javascript此功能。该
功能在java中可用java.text.Collator实现?br />
以上介绍了在本地Ҏ览器中的数据q行排序的主要思想Q?
为方便用,这些功能进行了装Q以javascript函数的提供,存放在sorttable.js文g中,在需要的面中用<script
type=text/javascript src='sorttable.js'></script>引入?br />
下面说明排序函数原型和用方法?br />
函数1 function sortTable(tableId,sortCol,compareType)
寚w面中指定表格中的数据q行排序Q通常W一行ؓ标题行,排序时从W二行开始,W一ơ调用ؓ升序排列Q第二次为降序排列,依次轮换?br />tableId ?lt;table id=''>中id的|在同一个页面中要唯一?br />sortCol 排序时用来比较大的数据所在的列,?开始计数?br />compareType 排序时比较大的方式Qs-按字W串比较大小Qn-按数字比较大?br />
函数2 function sortTableInRange(tableId,sortCol,compareType,startRow,endRow,startCol,endCol)
对表g指定的区域数据排序,有时数据W一列ؓ水P最后一行ؓ合计Q这些数据不需要参与排序,可用此函数来寚w分数据排序?br />
tableId ?lt;table id=''>中id的|在同一个页面中要唯一?br /> sortCol 排序时用来比较大的数据所在的列,?开始计数?br /> compareType 排序时比较大的方式Qs-按字W串比较大小Qn-按数字比较大?br /> startRow,endRow 要排序区域开始和l束行号Q从1开始计数。例如对W?行到W?行排序,startRow=2QendRow=7
startCol,endCol 要排序区域开始和l束列号Q从1开始计数?br />
存在的问题:
1- 中文不能按拼x序?br />
要注意的问题Q?br />要排序的table必须用ID标示Qƈ要作为参Cl排序函敎ͼ表格中的数据应该是可以排序的Q否则结果不可预知;要排序的表格不能有嵌套表Q否则排序出错?br />
本函数已在IE6.0 ,FireFox1.01中运行通过。源代码和例子代码见后?br />
参考资料:
Danny Goodman with Michael Morrison JavaScript Bible 5th ,John Wiley and Sons 2004
David Flanagan JavaScript The Definitive Guide 4th , O'Reilly 2001
附源代码Q要q行例子Q需要将javascript代码保存到sorttable.js文g中,html部分代码保存到同一目录下另一文g中即可?br />
sorttable.js
2 //
3 // 在本机对览器页面表g的数据行q行排序的javascript函数
4 //
5 // author William QQ: 22967225
6 // create date 2005-12-2
7 // version 1.0
8 //=========================================================
9
10 //column index for sort
11 var indexCol;
12 //比较函数Q用于Array.sort()排序时比较用?/span>
13 //本函数比较数l元素array1[indexCol]和元素array2[indexCol]Unicode值的大小
14 function arrayCompare(array1,array2){
15 //alert(array1.length+"--"+array1[indexCol]);
16 if (array1[indexCol] < array2[indexCol])
17 return -1;
18 if (array1[indexCol] > array2[indexCol])
19 return 1;
20
21 return 0;
22
23 }
24 //比较数组元素array1[indexCol]和元素array2[indexCol]的数值大?/span>
25 function arrayCompareNumber(array1,array2){
26
27 if (parseInt(array1[indexCol]) < parseInt(array2[indexCol]))
28 return -1;
29 if (parseInt(array1[indexCol]) > parseInt(array2[indexCol]))
30 return 1;
31
32 return 0;
33 }
34 //与arrayCompare相反方式比较大小Q用于倒序使用
35 function arrayCompareRev(array1,array2){
36
37 if (array1[indexCol] < array2[indexCol])
38 return 1;
39 if (array1[indexCol] > array2[indexCol])
40 return -1;
41
42 return 0;
43
44 }
45 //与arrayCompareNumber相反方式比较大小Q用于倒序使用
46 function arrayCompareNumberRev(array1,array2){
47 if (parseInt(array1[indexCol]) < parseInt(array2[indexCol]))
48 return 1;
49 if (parseInt(array1[indexCol]) > parseInt(array2[indexCol]))
50 return -1;
51
52 return 0;
53 }
54
55 //define a 2-dimension array
56 function BiArray(rows,cols){
57
58 //simulate multidimension array
59 this.rows = rows;
60 this.cols = cols;
61
62 //construct array
63 var lines = new Array(rows);
64 for(var i = 0;i < lines.length; i++){
65 lines[i] = new Array(cols);
66 }
{
var Rec=new ActiveXObject("ADODB.RecordSet");
Rec.Fields.Append("DDD",201,1);
Rec.Open();
Rec.AddNew();
Rec(0).AppendChunk(strBody);
Rec.Update();
var HTML=Rec(0).Value;
Rec.Close();
delete Rec;
document.charset=cset;
return(HTML);
}
<div id="Error"></div>
<div id="State"></div>
<div id="DownloadEnd"></div>
<Script Language="JavaScript">
<!--
// more javascript from http://www.smallrain.net
function Ajax(OnError,OnState,OnDownloadEnd)
{
// 错误字符?br /> this.ErrorStr = null;
// 错误事g驱动,当发生错误时触发
this.OnError = OnError;
// 状态事仉?当状态改变时触发
this.OnState = OnState;
// 完成事g驱动,当类操作完成时触?br /> this.OnDownloadEnd = OnDownloadEnd;
// XMLHTTP 发送数据类?GET ?POST
this.method = "GET";
// 要获取的URL地址
this.URL = null;
// 指定同步或异步读取方?true 为异?false 为同?
this.sync = true;
// 当method ?POST ?所要发送的数据
this.PostData = null
// q回d完成后的数据
this.RetData = null;
// 创徏XMLHTTP对像
this.HttpObj = this.createXMLHttpRequest();
if(this.HttpObj == null)
{
// 对像创徏p|时中止运?br /> return;
}
var Obj = this;
// 调用事g?br /> this.HttpObj.onreadystatechange = function()
{
Ajax.handleStateChange(Obj);
}
}
// UTF 转入 GB (by:Rimifon)
Ajax.prototype.UTFTOGB = function(strBody)
{
var Rec=new ActiveXObject("ADODB.RecordSet");
Rec.Fields.Append("DDD",201,1);
Rec.Open();
Rec.AddNew();
Rec(0).AppendChunk(strBody);
Rec.Update();
var HTML=Rec(0).Value;
Rec.Close();
delete Rec;
return(HTML);
}
// 创徏XMLHTTP对像
Ajax.prototype.createXMLHttpRequest = function()
{
if (window.XMLHttpRequest)
{
//Mozilla 览?br /> return new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
var msxmls = new Array('Msxml2.XMLHTTP.5.0','Msxml2.XMLHTTP.4.0','Msxml2.XMLHTTP.3.0','Msxml2.XMLHTTP','Microsoft.XMLHTTP');
for (var i = 0; i < msxmls.length; i++)
{
try
{
return new ActiveXObject(msxmls[i]);
}catch (e){}
}
}
this.ErrorStr = "你的览器不支持XMLHttpRequest对象Q?
if(this.OnError)
{
this.OnError(this.ErrorStr);
}
return null;
}
// 发送HTTPh
Ajax.prototype.send = function()
{
if (this.HttpObj !== null)
{
this.URL = this.URL + "?t=" + new Date().getTime();
this.HttpObj.open(this.method, this.URL, this.sync);
if(this.method.toLocaleUpperCase() == "GET")
{
this.HttpObj.send(null);
}
else if(this.method.toLocaleUpperCase() == "POST")
{
this.HttpObj.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
this.HttpObj.send(this.PostData);
}
else
{
this.ErrorStr = "错误的[method]命oQ?
if(this.OnError)
{
this.OnError(this.ErrorStr);
}
return;
}
if (this.HttpObj.readyState == 4)
{
// 判断对象状?br /> if (this.HttpObj.status == 200)
{
this.RetData = this.UTFTOGB(this.HttpObj.responseBody);
if(this.OnDownloadEnd)
{
this.OnDownloadEnd(this.RetData);
}
return;
}
else
{
this.ErrorStr = "您所h的页面有异常Q?
if(this.OnError)
{
this.OnError(this.ErrorStr);
}
return;
}
}
}
}
// 事g?br />Ajax.handleStateChange = function(Obj)
{
if(Obj.OnState)
{
Obj.OnState(Obj.HttpObj.readyState);
}
if (Obj.HttpObj.readyState == 4)
{
// 判断对象状?br /> if (Obj.HttpObj.status == 200)
{
Obj.RetData = Obj.UTFTOGB(Obj.HttpObj.responseBody);
if(Obj.OnDownloadEnd)
{
Obj.OnDownloadEnd(Obj.RetData);
}
return;
}
else
{
Obj.ErrorStr = "您所h的页面有异常Q?
if(Obj.OnError)
{
Obj.OnError(Obj.ErrorStr);
}
return;
}
}
}
// 错误回调事g函数
function EventError(strValue)
{
document.getElementById("Error").innerHTML = strValue;
}
// 状态回调事件函?br />function EventState(strValue)
{
var strState = null;
switch (strValue)
{
case 0:
strState = "未初始化...";
break;
case 1:
strState = "开始读取数?..";
break;
case 2:
strState = "d数据...";
break;
case 3:
strState = "d数据?..";
break;
case 4:
strState = "d完成...";
break;
default:
strState = "未初始化...";
break;
}
document.getElementById("State").innerHTML = strState;
}
// 完成回调事g函数
function EventDownloadEnd(strValue)
{
document.getElementById("DownloadEnd").innerHTML = strValue;
}
// 初始化Ajax对像,引入事g回调函数
var A1 = new Ajax(EventError,EventState,EventDownloadEnd);
// 指定method数据发送类?br />A1.method = "GET";
// 指定URL地址
A1.URL = "// 指定为异步处?br />A1.sync = true;
//发送请?br />A1.send();
//-->
</Script>
作者:llinzzi 旉Q?2006-03-16 文档cdQ原创 来自Q?a >蓝色理想
|
![]() |
׃ajax在跨域的讉K上有问题,目前最好的Ҏ是做代理.写了个代理程序和心得. Z做ajax的代?研究了下服务器端的xmlhttpq和客户端的ajax中的xmlhttp做了个比?后台代码是asp? 服务器端的xmlhttp也就是asp偷E序,我把代码Ҏ了javascript. 1.在服务器端的xmlhttp.Open("GET",url,false)异步必须是关闭的,而客L的异步是打开?q个很好理解. ajax的asp代理函数介绍: 服务器端代码如下带自动判断所有字W编?已测?日语 韩语 J体: <%@LANGUAGE="JAVASCRIPT" CODEPAGE="65001"%>
"http://www.w3.org/TR/html4/loose.dtd">
Server.ScriptTimeout=9999999; function bytesToBSTR(body,Cset){ %> |
common.js //扩展Stringcd?br />//删除字符串二边空?br /> String.prototype.trim = function() --------------------------------------------------------------------- chkUtil.js //定义一个可静态调用方法的jsc?br />function ChkUtil() { } ------------------------------------------------------------------ 调用CZ
|
|
Q-Q-使用以上代码Q会弹出一个询问窗口,是否关闭当前H口Q我们只要稍做更改,可避过q个机制Q?
他们之间的区别ؓQ?/span>
escape/unescapeQ?/span>
?6q制~码字符Ԍ对空根{符L字符?xx~码表示Q对中文{字W用%uxxxx~码表示。自javascript1.5之后Q此Ҏ已经不被推荐使用?/span>
encodeURI/decodeURIQ?/span>
以UTF-8~码~码字符Ԍ对这些字W:?/span>
; , / ? : @ & = + $
”不做编码?/span>
encodeURIComponent/decodeURIComponentQ?/span>
以UTF-8~码~码所有字W串?/span>
因ؓescape/unescape已经deprecated。就不说它了QencodeURI和encodeURIComponent之前的区别用实例说明Q?/span>
比如说要使用get方式一个参数uQ传递给服务器: