如何对整数数组进行排序(使用串排序算法)?C#
关于我的问题:我在学校有一个作业,我没有通过,因为我的代码运行太慢了。现在我必须修复和研究它,因为我必须解释我是如何修复它的以及它是如何工作的 我的问题是:我可以修复代码中的哪些部分来归档O(n^2)的平均性能?我怎样才能让它跑得更快 所需:如何对整数数组进行排序(使用串排序算法)?C#,c#,sorting,C#,Sorting,关于我的问题:我在学校有一个作业,我没有通过,因为我的代码运行太慢了。现在我必须修复和研究它,因为我必须解释我是如何修复它的以及它是如何工作的 我的问题是:我可以修复代码中的哪些部分来归档O(n^2)的平均性能?我怎样才能让它跑得更快 所需: 按升序对整数数组进行排序 算法的平均性能必须为O(n^2) 不得使用array的Sort()方法 System.Collections.Generic或其他库是不允许的(只允许使用系统库) 必须使用串排序算法 这是我到目前为止尝试过的,但它的工作方式太
- 按升序对整数数组进行排序
- 算法的平均性能必须为O(n^2)
- 不得使用
的array
方法Sort()
或其他库是不允许的(只允许使用系统库)System.Collections.Generic
- 必须使用串排序算法
static public int[] StrandSortAscending(int[] p1)
{
int[] p2,
p3;
int p1s1,
p2s1,
p2s2,
p3s1,
p3s2,
n;
p2 = new int[p1.Length];
p3 = new int[p1.Length];
Reset(ref p2);
Reset(ref p3);
p1s1 = p1.Length;
p3s1 = 0;
while (p1s1 != 0)
{
n = int.MinValue;
p2s1 = 0;
for (int i8 = 0; i8 < p1.Length; i8++)
{
if (p1[i8] != int.MaxValue)
{
if (p1[i8] >= n)
{
p2[p2s1] = p1[i8];
n = p1[i8];
p1[i8] = int.MaxValue;
p1s1--;
p2s1++;
}
}
}
int p3p,
zs;
bool pn = false;
for (int i5 = 0; i5 < p2.Length; i5++)
{
p3p = int.MinValue;
for (int i6 = 0; i6 < p3.Length; i6++)
{
if (pn)
{
zs = p3[i6];
p3[i6] = p3p;
p3p = zs;
}
else
{
if (p2[i5] >= p3p && p2[i5] <= p3[i6])
{
p3p = p3[i6];
p3[i6] = p2[i5];
}
}
}
}
Reset(ref p2);
}
return p3;
}
static void Reset(ref int[] a)
{
for (int i = 0; i < a.Length; i++)
a[i] = int.MaxValue;
}
static public int[]strandsortsupsing(int[]p1)
{
int[]p2,
p3;
int p1s1,
p2s1,
p2s2,
p3s1,
p3s2,
N
p2=新整数[p1.长度];
p3=新整数[p1.长度];
重置(参考p2);
复位(参考p3);
p1s1=p1.长度;
p3s1=0;
而(p1s1!=0)
{
n=int.MinValue;
p2s1=0;
for(inti8=0;i8=n)
{
p2[p2s1]=p1[i8];
n=p1[i8];
p1[i8]=int.MaxValue;
p1s1--;
p2s1++;
}
}
}
int p3p,
zs;
bool pn=假;
for(inti5=0;i5 如果(p2[i5]>=p3p&&p2[i5]好的话,我觉得很无聊,想帮忙(而且,一个有那么多评论的问题不能没有答案:D),所以就把它转换成C#,但过了一会儿,用户补充说他不能使用泛型
因此,我发布了一个完整的实现,一个带有泛型,另一个带有自己的LinkedList,虽然有点长,但它可以工作(以Wikipedia为例,一步一步,它的行为与示例表完全相同),并且它也被注释了,因此很容易理解(链表代码没有注释)
它来了
public class StrandSort
{
public static int[] SortWithGenerics(int[] Values)
{
List<int> Original = new List<int>();
List<int> Result = new List<int>();
List<int> Sublist = new List<int>();
Original.AddRange(Values);
//While we still have numbers to sort
while (Original.Count > 0)
{
//Clear sublist and take first available number from original to the new sublist
Sublist.Clear();
Sublist.Add(Original[0]);
Original.RemoveAt(0);
//Iterate through original numbers
for (int x = 0; x < Original.Count; x++)
{
//If the number is bigger than the last item in the sublist
if (Original[x] > Sublist[Sublist.Count - 1])
{
//Add it to the sublist and remove it from original
Sublist.Add(Original[x]);
Original.RemoveAt(x);
//Roll back one position to compensate the removed item
x--;
}
}
//If this is the first sublist
if (Result.Count == 0)
Result.AddRange(Sublist); //Add all the numbers to the result
else
{
//Iterate through the sublist
for (int x = 0; x < Sublist.Count; x++)
{
bool inserted = false;
//Iterate through the current result
for (int y = 0; y < Result.Count; y++)
{
//Is the sublist number lower than the current item from result?
if (Sublist[x] < Result[y])
{
//Yes, insert it at the current Result position
Result.Insert(y, Sublist[x]);
inserted = true;
break;
}
}
//Did we inserted the item because found it was lower than one of the result's number?
if (!inserted)
Result.Add(Sublist[x]);//No, we add it to the end of the results
}
}
}
//Return the results
return Result.ToArray();
}
public static int[] SortWithoutGenerics(int[] Values)
{
IntLinkedList Original = new IntLinkedList();
IntLinkedList Result = new IntLinkedList();
IntLinkedList Sublist = new IntLinkedList();
Original.AddRange(Values);
//While we still have numbers to sort
while (Original.Count > 0)
{
//Clear sublist and take first available number from original to the new sublist
Sublist.Clear();
Sublist.Add(Original.FirstItem.Value);
Original.Remove(Original.FirstItem);
IntLinkedItem currentOriginalItem = Original.FirstItem;
//Iterate through original numbers
while (currentOriginalItem != null)
{
//If the number is bigger than the last item in the sublist
if (currentOriginalItem.Value > Sublist.LastItem.Value)
{
//Add it to the sublist and remove it from original
Sublist.Add(currentOriginalItem.Value);
//Store the next item
IntLinkedItem nextItem = currentOriginalItem.NextItem;
//Remove current item from original
Original.Remove(currentOriginalItem);
//Set next item as current item
currentOriginalItem = nextItem;
}
else
currentOriginalItem = currentOriginalItem.NextItem;
}
//If this is the first sublist
if (Result.Count == 0)
Result.AddRange(Sublist); //Add all the numbers to the result
else
{
IntLinkedItem currentSublistItem = Sublist.FirstItem;
//Iterate through the sublist
while (currentSublistItem != null)
{
bool inserted = false;
IntLinkedItem currentResultItem = Result.FirstItem;
//Iterate through the current result
while (currentResultItem != null)
{
//Is the sublist number lower than the current item from result?
if (currentSublistItem.Value < currentResultItem.Value)
{
//Yes, insert it at the current Result position
Result.InsertBefore(currentResultItem, currentSublistItem.Value);
inserted = true;
break;
}
currentResultItem = currentResultItem.NextItem;
}
//Did we inserted the item because found it was lower than one of the result's number?
if (!inserted)
Result.Add(currentSublistItem.Value);//No, we add it to the end of the results
currentSublistItem = currentSublistItem.NextItem;
}
}
}
//Return the results
return Result.ToArray();
}
public class IntLinkedList
{
public int count = 0;
IntLinkedItem firstItem = null;
IntLinkedItem lastItem = null;
public IntLinkedItem FirstItem { get { return firstItem; } }
public IntLinkedItem LastItem { get { return lastItem; } }
public int Count { get { return count; } }
public void Add(int Value)
{
if (firstItem == null)
firstItem = lastItem = new IntLinkedItem { Value = Value };
else
{
IntLinkedItem item = new IntLinkedItem{ PreviousItem = lastItem, Value = Value };
lastItem.NextItem = item;
lastItem = item;
}
count++;
}
public void AddRange(int[] Values)
{
for (int buc = 0; buc < Values.Length; buc++)
Add(Values[buc]);
}
public void AddRange(IntLinkedList Values)
{
IntLinkedItem item = Values.firstItem;
while (item != null)
{
Add(item.Value);
item = item.NextItem;
}
}
public void Remove(IntLinkedItem Item)
{
if (Item == firstItem)
firstItem = Item.NextItem;
if (Item == lastItem)
lastItem = Item.PreviousItem;
if(Item.PreviousItem != null)
Item.PreviousItem.NextItem = Item.NextItem;
if (Item.NextItem != null)
Item.NextItem.PreviousItem = Item.PreviousItem;
count--;
}
public void InsertBefore(IntLinkedItem Item, int Value)
{
IntLinkedItem newItem = new IntLinkedItem { PreviousItem = Item.PreviousItem, NextItem = Item, Value = Value };
if (Item.PreviousItem != null)
Item.PreviousItem.NextItem = newItem;
Item.PreviousItem = newItem;
if (Item == firstItem)
firstItem = newItem;
count++;
}
public void Clear()
{
count = 0;
firstItem = lastItem = null;
}
public int[] ToArray()
{
int[] results = new int[Count];
int pos = 0;
IntLinkedItem item = firstItem;
while (item != null)
{
results[pos++] = item.Value;
item = item.NextItem;
}
return results;
}
}
public class IntLinkedItem
{
public int Value;
internal IntLinkedItem PreviousItem;
internal IntLinkedItem NextItem;
}
}
公共类StrandSort
{
公共静态int[]SortWithGenerics(int[]值)
{
List Original=新列表();
列表结果=新列表();
列表子列表=新列表();
原始.AddRange(值);
//虽然我们还有数字要排序
而(原始计数>0)
{
//清除子列表,并将第一个可用编号从原始列表移到新的子列表
Sublist.Clear();
子列表添加(原始[0]);
原始。移除(0);
//遍历原始数字
对于(int x=0;x子列表[Sublist.Count-1])
{
//将其添加到子列表并从原始列表中删除
子列表添加(原始[x]);
原件。移除(x);
//向后滚动一个位置以补偿拆下的项目
x--;
}
}
//如果这是第一个子列表
如果(Result.Count==0)
Result.AddRange(子列表);//将所有数字添加到结果中
其他的
{
//遍历子列表
for(int x=0;x0)
{
//清除子列表,并将第一个可用编号从原始列表移到新的子列表
Sublist.Clear();
子列表.Add(Original.FirstItem.Value);
原件。移除(原件。第一项);
IntLinkedItem currentOriginalItem=origin.FirstItem;
//遍历原始数字
while(currentOriginalItem!=null)
{
//如果数字大于子列表中的最后一项
如果(currentOriginalItem.Value>子列表)。
public class StrandSort
{
public static int[] SortWithGenerics(int[] Values)
{
List<int> Original = new List<int>();
List<int> Result = new List<int>();
List<int> Sublist = new List<int>();
Original.AddRange(Values);
//While we still have numbers to sort
while (Original.Count > 0)
{
//Clear sublist and take first available number from original to the new sublist
Sublist.Clear();
Sublist.Add(Original[0]);
Original.RemoveAt(0);
//Iterate through original numbers
for (int x = 0; x < Original.Count; x++)
{
//If the number is bigger than the last item in the sublist
if (Original[x] > Sublist[Sublist.Count - 1])
{
//Add it to the sublist and remove it from original
Sublist.Add(Original[x]);
Original.RemoveAt(x);
//Roll back one position to compensate the removed item
x--;
}
}
//If this is the first sublist
if (Result.Count == 0)
Result.AddRange(Sublist); //Add all the numbers to the result
else
{
//Iterate through the sublist
for (int x = 0; x < Sublist.Count; x++)
{
bool inserted = false;
//Iterate through the current result
for (int y = 0; y < Result.Count; y++)
{
//Is the sublist number lower than the current item from result?
if (Sublist[x] < Result[y])
{
//Yes, insert it at the current Result position
Result.Insert(y, Sublist[x]);
inserted = true;
break;
}
}
//Did we inserted the item because found it was lower than one of the result's number?
if (!inserted)
Result.Add(Sublist[x]);//No, we add it to the end of the results
}
}
}
//Return the results
return Result.ToArray();
}
public static int[] SortWithoutGenerics(int[] Values)
{
IntLinkedList Original = new IntLinkedList();
IntLinkedList Result = new IntLinkedList();
IntLinkedList Sublist = new IntLinkedList();
Original.AddRange(Values);
//While we still have numbers to sort
while (Original.Count > 0)
{
//Clear sublist and take first available number from original to the new sublist
Sublist.Clear();
Sublist.Add(Original.FirstItem.Value);
Original.Remove(Original.FirstItem);
IntLinkedItem currentOriginalItem = Original.FirstItem;
//Iterate through original numbers
while (currentOriginalItem != null)
{
//If the number is bigger than the last item in the sublist
if (currentOriginalItem.Value > Sublist.LastItem.Value)
{
//Add it to the sublist and remove it from original
Sublist.Add(currentOriginalItem.Value);
//Store the next item
IntLinkedItem nextItem = currentOriginalItem.NextItem;
//Remove current item from original
Original.Remove(currentOriginalItem);
//Set next item as current item
currentOriginalItem = nextItem;
}
else
currentOriginalItem = currentOriginalItem.NextItem;
}
//If this is the first sublist
if (Result.Count == 0)
Result.AddRange(Sublist); //Add all the numbers to the result
else
{
IntLinkedItem currentSublistItem = Sublist.FirstItem;
//Iterate through the sublist
while (currentSublistItem != null)
{
bool inserted = false;
IntLinkedItem currentResultItem = Result.FirstItem;
//Iterate through the current result
while (currentResultItem != null)
{
//Is the sublist number lower than the current item from result?
if (currentSublistItem.Value < currentResultItem.Value)
{
//Yes, insert it at the current Result position
Result.InsertBefore(currentResultItem, currentSublistItem.Value);
inserted = true;
break;
}
currentResultItem = currentResultItem.NextItem;
}
//Did we inserted the item because found it was lower than one of the result's number?
if (!inserted)
Result.Add(currentSublistItem.Value);//No, we add it to the end of the results
currentSublistItem = currentSublistItem.NextItem;
}
}
}
//Return the results
return Result.ToArray();
}
public class IntLinkedList
{
public int count = 0;
IntLinkedItem firstItem = null;
IntLinkedItem lastItem = null;
public IntLinkedItem FirstItem { get { return firstItem; } }
public IntLinkedItem LastItem { get { return lastItem; } }
public int Count { get { return count; } }
public void Add(int Value)
{
if (firstItem == null)
firstItem = lastItem = new IntLinkedItem { Value = Value };
else
{
IntLinkedItem item = new IntLinkedItem{ PreviousItem = lastItem, Value = Value };
lastItem.NextItem = item;
lastItem = item;
}
count++;
}
public void AddRange(int[] Values)
{
for (int buc = 0; buc < Values.Length; buc++)
Add(Values[buc]);
}
public void AddRange(IntLinkedList Values)
{
IntLinkedItem item = Values.firstItem;
while (item != null)
{
Add(item.Value);
item = item.NextItem;
}
}
public void Remove(IntLinkedItem Item)
{
if (Item == firstItem)
firstItem = Item.NextItem;
if (Item == lastItem)
lastItem = Item.PreviousItem;
if(Item.PreviousItem != null)
Item.PreviousItem.NextItem = Item.NextItem;
if (Item.NextItem != null)
Item.NextItem.PreviousItem = Item.PreviousItem;
count--;
}
public void InsertBefore(IntLinkedItem Item, int Value)
{
IntLinkedItem newItem = new IntLinkedItem { PreviousItem = Item.PreviousItem, NextItem = Item, Value = Value };
if (Item.PreviousItem != null)
Item.PreviousItem.NextItem = newItem;
Item.PreviousItem = newItem;
if (Item == firstItem)
firstItem = newItem;
count++;
}
public void Clear()
{
count = 0;
firstItem = lastItem = null;
}
public int[] ToArray()
{
int[] results = new int[Count];
int pos = 0;
IntLinkedItem item = firstItem;
while (item != null)
{
results[pos++] = item.Value;
item = item.NextItem;
}
return results;
}
}
public class IntLinkedItem
{
public int Value;
internal IntLinkedItem PreviousItem;
internal IntLinkedItem NextItem;
}
}
static public int[] SortCorrectedUserCode(int[] Source)
{
int[] Sublist,
Results;
int ItemsLeft,
SublistPos,
ResultPos;//new variable to store current pos in results
//n; n was useless
Sublist = new int[Source.Length];
Results = new int[Source.Length];
//Avoid resets just using an integer to track array lengths
//Reset(ref Sublist);
//Reset(ref Results);
ItemsLeft = Source.Length;
ResultPos = 0;
while (ItemsLeft != 0)
{
//n = int.MinValue;
SublistPos = 0;
for (int currentSourcePos = 0; currentSourcePos < Source.Length; currentSourcePos++)
{
if (Source[currentSourcePos] != int.MaxValue)
{
//Added special treatment for first item in sublist (copy it yes or yes ;D)
if (SublistPos == 0 || Source[currentSourcePos] > Sublist[SublistPos])
{
Sublist[SublistPos] = Source[currentSourcePos];
//n = Source[currentSourcePos]; useless
Source[currentSourcePos] = int.MaxValue;
ItemsLeft--;
SublistPos++;
}
}
}
//int p3p, zs;
//pn is never true...
//bool pn = false;
//Sublist was being iterated for all it's length, not only for the current items
//for (int currentSublistPos = 0; currentSublistPos < Sublist.Length; currentSublistPos++)
for (int currentSublistPos = 0; currentSublistPos < SublistPos; currentSublistPos++)
{
//p3p = int.MinValue;
bool inserted = false;
//Results was being iterated for all it's length, not only for current items
//for (int currentResultPos = 0; currentResultPos < Results.Length; currentResultPos++)
for (int currentResultPos = 0; currentResultPos < ResultPos; currentResultPos++)
{
//This part was never used...
//if (pn)
//{
// zs = Results[currentResultPos];
// Results[currentResultPos] = p3p;
// p3p = zs;
//}
//else
//{
//This IF was wrong, when the code entered this piece of code it started
//for subsequent iterations in the current loop to copy data from sublist to list, which is not correct ... I think, not sure
//because it's really confusing
//if (Sublist[currentSublistPos] >= p3p && Sublist[currentSublistPos] <= Results[currentResultPos])
//{
//p3p = Results[currentResultPos];
//Results[currentResultPos] = Sublist[currentSublistPos];
//}
//}
//New code, if the item at sublist is lower than the one at results then insert item in current position
if (Sublist[currentSublistPos] < Results[currentResultPos])
{
InsertInArray(currentResultPos, Sublist[currentSublistPos], Results);
inserted = true;
break;
}
}
//Did we inserted the item?
if (!inserted)
Results[ResultPos] = Sublist[currentSublistPos]; //If no then just add it to the end of the results
ResultPos++;
}
//Reset(ref Sublist);
}
return Results;
}
//Helper function to insert a value in an array and displace values to the right
static void InsertInArray(int Index, int Value, int[] Target)
{
//Create temp array of right items
int[] tempArray = new int[(Target.Length - Index) - 1];
//Copy items to temp array
Array.Copy(Target, Index, tempArray, 0, tempArray.Length);
//Set value at index
Target[Index] = Value;
//Copy values from temp array to correct position
Array.Copy(tempArray, 0, Target, Index + 1, tempArray.Length);
}
while (p1s1 != 0)
{
n = int.MinValue;
p2s1 = 0;
for (int i8 = 0; i8 < p1.Length; i8++)
{
if (p1[i8] != int.MaxValue)
{
if (p1[i8] >= n)
{
p2[p2s1] = p1[i8];
n = p1[i8];
p1[i8] = int.MaxValue;
p1s1--;
p2s1++;
}
}
}
if (p1[i8] != int.MaxValue)
{
if (p1[i8] >= n)