2009-01-20 6 views
1

이것은 아마도 간단한 질문 일 것입니다. 제가 약 20-50 개의 항목이있는 작은 목록이 있다고 가정 해 봅시다. 뭔가 같은목록의 중간에 뭔가를 삽입하는 좋은 방법은 무엇입니까?

class Item 
{ 
    int ItemNumber; 
    int OrderNumber; 
    string Name; 
} 

stored in something like 
List<Item> 

이것은 OrderNumber를 1, 2,3,4, ... (50)로부터 어디로에서 일반적인리스트 또는 배열되어 저장된다. 일을 더 쉽게하려면 OrderNumber가 ListSuite에 의해 이미 정렬되어 있다고 가정 해 봅시다.

Item.OrderNumber = 30을 Item.OrderNumber = 20 또는 그와 비슷한 부분으로 옮기고 싶습니다. 그 일을 할 때, 20 세 이상은 이제 20 세가 될 때까지 21 세가되도록 21, 21 세가 22 세가 될 때까지 이동해야합니다. Item.OrderNumber = 30 일 때 다른 방법으로 이동해야합니다. Item.OrderNumber = 34로 이동되고 모든 것이 아래쪽으로 이동되어야합니다.

나는 목록을 몇 번 버블 링하는 것에 대해 생각하고 있지만, 이것을 수행하는 더 좋은 방법이 있기를 바랍니다. 리스트 크기는 작지만, 이것은 다양한 다른 것들을 위해 많이해야합니다.

편집 : 알려주세요. 결과는 결국 일부 유형의 트랜잭션에서 데이터베이스에 저장되어야합니다. 만약 이중 연결리스트를 사용하면

답변

0
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

public class Class1 
{      
    static void Main() 
    { 
     var beatles = new LinkedList<string>(); 

     beatles.AddFirst("John");       
     LinkedListNode<string> nextBeatles = beatles.AddAfter(beatles.First, "Paul"); 
     nextBeatles = beatles.AddAfter(nextBeatles, "George"); 
     beatles.AddAfter(nextBeatles, "Ringo"); 


     LinkedListNode<string> paulsNode = beatles.NodeAt(1); // middle's index 
     LinkedListNode<string> recentHindrance = beatles.AddBefore(paulsNode, "Yoko"); 
     recentHindrance = beatles.AddBefore(recentHindrance, "Aunt Mimi"); 
     beatles.AddBefore(recentHindrance, "Father Jim"); 


     Console.WriteLine("{0}", string.Join("\n", beatles.ToArray())); 

     Console.ReadLine();      
    } 
} 

public static class Helper 
{ 
    public static LinkedListNode<T> NodeAt<T>(this LinkedList<T> l, int index) 
    { 
     LinkedListNode<T> x = l.First; 

     while ((index--) > 0) x = x.Next; 

     return x; 
    } 
} 
0

은하면 (19) 후에 위치에 OrderNumber를 = 30의 매우 저렴한 삽입 않거나 제 전에이 30보다 작은 OrderNumber를까지 반복하고 각 순서를 증가시킬 수있다 1. 목록에서 항목을 위로 이동하려면 반대 방향으로 이동하십시오.

2

List<T>이어야합니까? 그렇지 않은 경우 SortedList<TKey, TValue> 또는 SortedDictionary<TKey, TValue>을 사용하는 것이 좋습니다. 그런 다음 OrderNumber를 키로 사용하여 콜렉션이 작업을 수행하도록 할 수 있습니다.

Alterantively, List<T> 당신이 주문 번호로 비교하는 적절한 IComparer<T>으로 List<T>.BinarySearch을 사용할 수 있습니다 - 당신은 것입니다 : 그것은 국적을 상실하는 것처럼

int position = list.BinarySearch(newOrder, orderComparer); 
list.Insert(position >= 0 ? position : ~position, newOrder); 

당신은 당신의 코드를 통해 같은 IComparer<T> 인스턴스를 사용할 수 있습니다 .

EDIT :이 솔루션은 Robert Wagner's answer에서 제안 된대로 다른 항목의 OrderNumber를 변경하지 않습니다.

+0

이 목록 입니다 번호 다시 매기기 항목 을 제거 .BinarySearch 스킵리스트 IMPL에 대한 인터페이스를 제공합니다.? – mabbit

+0

이것은 배열로 뒷받침 된 목록의 정상적인 이진 검색 일뿐입니다. –

0

목록을 채운 후 정렬하고 끝 부분에 물건을 붙여서 채 웁니다. Skeet이 말하는대로 항상 정렬해야합니다.

1

제가 올바르게 이해한다면, 어떤 이유에서 건 객체 내부에 OrderNumber를 유지하려하지만, 목록에 새 객체를 추가하고 다른 모든 객체가 OrderNumber를 조정하여 새로운 하나. 또한 목록에있는 항목의 실제 순서는 중요하지 않습니다.모든 항목을 통해

삽입 루프 한 곳으로 주문 번호를 증가 :이 목록을 포장하고 다음을했던 자신의 작업 (이동/삽입/제거 기능을 구현하여 수행 할 수

주문 번호> = 새 항목의 주문 번호가

모든 항목을 항목 루프를 제거 를 제거 목록에 항목을 추가하고 하나를 사용하여 주문 번호를 감소 어디에서 주문 번호> 제품의 주문 번호를 제거

이동 이 항목 이 삽입 항목

+0

예, OrderNumbers 업데이트에 대한 귀하의 권리. – danmine

관련 문제