C# problem z posortowaniem listy jednokier.

0

Witam,
mam na zadanie domowe z algorytmow posortowac liste jednokierunkowa, wiem ze wszedzie sa opisy jak to zrobic tylko wszystko w c++, a skoro sie srednio znam na programowaniu, mimo spedzonych wielu godzin nie moglem tego zrobic w c#.

Oto moja lista :

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

namespace ListaJednokierunkowa
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            int s, i, xx;
            int[] tablica;

            List<int> lista = new List<int>();
            Console.WriteLine("Podaj rozmiar/wielkość tablicy:");
            string a;
            a = Console.ReadLine();
            s = int.Parse(a);
            tablica = new int[s];
            Random Generator = new Random();

            ListaNaPoczątku DopisywanieNaPoczątku;
            ElementListy DopisywanieNaKońcu;


            Generator = new Random();
            xx = Generator.Next(123);

            DopisywanieNaPoczątku = new ListaNaPoczątku((double)xx);
            DopisywanieNaKońcu = new ElementListy((double)xx);

            for (i = 0; i < tablica.Length; i++)
            {
                tablica[i] = xx = Generator.Next(123);

                DopisywanieNaPoczątku.DodajNaPoczątek((double)xx);
                DopisywanieNaKońcu.Dopisz((double)xx);
            }//next i


            Console.WriteLine("\n         Początkowa lista");
            DopisywanieNaPoczątku.Korzeń.Wyświetl(false);
            Console.WriteLine("\n\n\nLista zapisywana od końca:");
            DopisywanieNaKońcu.Wyświetl(false);
            

            DopisywanieNaPoczątku.UsuńListęZPamięci(); //Usuwanie listy z pamięci
            DopisywanieNaKońcu.Usuń();
            DopisywanieNaKońcu = null;

            Console.ReadKey();
        }
       
        }
    }
    public class ListaNaPoczątku
    {
        public ElementListy Korzeń;
        public ElementListy NowyElement;

        //Konstruktor
        public ListaNaPoczątku(double x)
        {
            Korzeń = new ElementListy(x);
            NowyElement = null;

        }//Koniec konstruktora

        public void DodajNaPoczątek(double x)
        {
            NowyElement = new ElementListy(x);
            NowyElement.Następny = Korzeń;
            Korzeń = NowyElement;
        }//Koniec dopisywania do początku listy


        //Metoda usuwająca element z listy
        public void UsuńElement(double x)
        {
            ElementListy Pomocniczy;

            if (Korzeń.Wartość == x)
            {
                Pomocniczy = Korzeń.Następny;
                Korzeń = null;//Usuwanie z pamięci!!!
                Korzeń = Pomocniczy;
            }

            Korzeń.UsuńZListy(x); //Usuwa pozostałe elementy przechowujące wartość x

        }//Koniec metody usuwającej element z listy

        public void UsuńListęZPamięci()
        {
            Korzeń.Usuń();
            Korzeń = null;
        }//Koniec metody usuwającej listę z pamięci

    }//Koniec klasy ListaNaPoczątku
    public class ElementListy
    {
        public double Wartość;
        public ElementListy Następny;

        //Konstruktor
       
        public ElementListy(double x)
        {
            Wartość = x;			//Zapamiętanie
            Następny = null;	//Wskaźnik = null
        }//Koniec konstruktora

        //Metoda dopisująca do końca listy
        public void Dopisz(double x)
        {
            if (Następny == null)
            {
                Następny = new ElementListy(x);
            }
            else
            {
                Następny.Dopisz(x);
            }
            
        }//Koniec metody dopisującej do końca listy

        
        public bool Szukaj(double x)
        {
            bool wynik;

            wynik = false; //Domyślna wartość!

            if (Wartość == x) wynik = true;
            if ((wynik == false) && (Następny != null))
            {
                wynik = Następny.Szukaj(x);
            }

            return wynik;



        }//koniec metody szukającej

        //Metoda do usuwania elementu ze środka i z końca listy
        public void UsuńZListy(double x)
        {
            ElementListy Pomoc;

            if (Następny != null)
            {
                if (Następny.Wartość == x)
                {

                    if (Następny.Następny == null) //Usuwanie na końcu listy
                    {
                        Następny = null;
                    }
                    if (Następny.Następny != null) //Usuwanie w środku listy
                    {
                        Pomoc = Następny;
                        Następny = Następny.Następny;
                        Pomoc = null;//Usunięcie z pamięci!!
                    }//end if

                }
                if (Następny.Wartość != x)
                {
                    Następny.UsuńZListy(x);
                }//end if
            }//end if

        }//Koniec metody usuwającej ze środka i z końca listy


        //Metoda usuwająca listę z pamięci RAM (zostaje tylko korzeń)
        public void Usuń()
        {
            if (Następny != null)
            {
                if (Następny.Następny != null)
                {
                    Następny.Usuń();
                }

                Następny = null;

            }//end if

        }//koniec metody usuwającej listę z pamięci

        //Metoda wyświetlająca zawartość listy
        public void Wyświetl(bool NastępnaLinia)
        {
            string Dodatek;

            Dodatek = "";

            if (NastępnaLinia == true) Dodatek = "\n";

            Console.Write("" + Wartość + ", " + Dodatek);

            if (Następny != null) Następny.Wyświetl(NastępnaLinia);
        }//Koniec metody wyświetlającej zawartość listy

    }//Koniec klasy ElementListy



Z prezentacji z wykladu poskladalem cos takiego:

using System;
 
namespace lista
{
    public class ElementListy
 
    {
         private ElementListy NowyElement;
 
         public double Wartość;
         public ElementListy Następny;
         public ElementListy(double x)
      {
        Wartość = x;
        Następny = null;
      }
    }
 
          private ElementListy Korzeń;
          int i;
          for(i = 0; i < Tablica.Lenght; i++)
             {
           if(i == 0)
           Korzeń = new ElementListy(Tablica[0]);
             }
                public ElementListy Nowy;
                if(x < Korzeń.Wartość)
                      {
                        Nowy = new ElementListy(x);
                        Następny = Korzeń;
                        Korzeń = Nowy;
                        Nowy = null;
                      }
       public class ElementListy
{
      public double Wartość;
      public ElementListy Następny;
      public ElementListy(double x)
      {
            Wartość = x;
            Następny = null;
      }
      public void DopiszDoListy(double x)
       if(this.Wartość < x)
    {
       if(this.Następny == null)Następny = new ElementListy(x);
       else
    {
       if(Następny.Wartość < x) Następny.DopiszDoListy(x);
       else
    {
       NowyElement = new ElementListy(x);
       NowyElement.Następny = this.Następny;
       Następny = NowyElement;
       NowyElemed nt = null;
   } 
   }
   }
if(this.Wartość == x)
    {
     NowyElement = new ElementListy(x);
     NowyElement.Następny = this.Następny;
     this.Następny = NowyElement;
     NowyElement = null;
    }

Teraz nie wiem jak to poskladac w calosc i dopisac aby mi sortowalo ta liste, licze na wasza pomoc!
dzieki

1

Dobra lista listą, ale w C# implementowanie własnej listy o funkcjonalności wbudowanej nie ma najmniejszego sensu. Masz do dyspozycji listę z System.Collections.Generic, po co bawić się we własną implementację tego samego, a nawet gorszego? We wbudowanym List<T> masz sortowanie w jednej metodzie + własny sortowacz musisz napisać jeżeli ma to być niestandardowe. Aczkolwiek jak bardzo zależy Ci na implementacji tego w C# to skoro masz kod w C++ to łatwo Ci będzie przekonwertować to na C++, bo będzie identycznie prócz zamiast np. wskaźników będzie referencja itd.

0

Probuje zrobic tylko to na co nakierowuje nas prowadzacy:) Napisalem juz, ze probowalem to zrobic jednak srednio mi to wychodzi, gdyz srednio dobry z programownia jestem;d ,
kod z c++ znalazlem w necie:
http://wklej.org/id/227107/

void SortujListe()
{
  cout << "\n\nLista posortowana:\n";
  for(int i=0; i<50; i++)
	{
	 a=start;       //
	 b=start->next; // ustawienie wskaznikow na poczatek listy
   	 c=b->next;     //
	 temp=c;        //
	 for(a; c->next;) // rownoznaczne for(int j=0; j<50; j++)
		{
			if((c->next) && (c->wartosc < b->wartosc)) // najpierw sprawdzamy czy nie koniec listy a potem stosunek wartosci sasiednich elementow listy
			{
				temp=b->next;          //  temp bo zaraz stracimy adres elementu b
				b->next=temp->next;    //
				temp->next=b;          //  manipulacja wskaznikami, np. z fragmentu listy 3,5,2 robimy 3,2,5
				a->next=c;             //
				temp=c;                //
				
				c=a->next->next->next;  // aktualizacja wskaznikow
				a=a->next;              // j.w.
			}
			else if(c->next)  // jezeli wartosci rosnace (w porzadku) to lecimy dalej
			{
				a=a->next; //     3,4,5,6
				b=b->next; //     a,b,c, ->
				c=c->next; // ->    a,b,c
			}
		}
	}
	WyswietlListe();
}

Skoro to takie latwe moglbys mi to pomoc wczepic do mojego 1 kodu;p?

1

Popatrz na to, co zapisałeś z wykładu. Nie twórz listy jako obiektu List<type>, tylko sam napisz sobie klasę i z jej obiektów stwórz listę jednokierunkową w ten sposób, że każdy (oprócz ostatniego) jej element (obiekt Twojej klasy) będzie posiadał zmienną przechowującą referencję do następnego elementu. Wydaje mi się, że tak powinno być, aczkolwiek może istnieć jeszcze jakiś inny, nieznany mi sposób stworzenia takiej listy. Przypuszczam, że Twój Wykładowca chce pokazać jak działa lista, żeby potem przejść do bardziej skomplikowanych struktur, dla których nie ma osobnych klas w c#. Skminię jeszcze jakiś konkret jak ja to widzę i napiszę Ci to pewnie ogarniesz ;)

0

Dzieki, bylbym bardzo wdzieczny:D

1

ok, tak na szybkiego wyczarowałem coś takiego:

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

namespace List
{
    class Program
    {
        public static Random rand = new Random();
        public static ListElem root;

        public static void PrintList(ListElem root)
        {
            ListElem temp1 = root;
            while(temp1 != null)
            {
                Console.Write(temp1.value+", ");
                temp1 = temp1.next;
            }
        }
        static void Main(string[] args)
        {
            ListElem temp1;
            ListElem temp2 = new ListElem();
            root = new ListElem(temp2);
            int cnt = 10;
            for (int i = 0; i < cnt; i++)
            {
                temp1 = new ListElem();
                temp2.next = temp1;
                temp2 = temp1;
            }

            PrintList(root);

            Console.ReadLine();
        }

    }

    class ListElem
    {
        public ListElem next;
        public int value;


        public ListElem()
        {
            next = null;
            value = Program.rand.Next(11);
        }
        public ListElem(int value)
        {
            next = null;
            this.value = value;
        }
        public ListElem(ListElem next)
        {
            this.next = next;
            value = Program.rand.Next(11);
        }
        public ListElem(int value, ListElem next)
        {
            this.next = next;
            this.value = value;
        }

        public bool MoveForward()
        {
            if (next != null)
            {
                ListElem temp1 = next.next;
                next.next = this;
                Program.root = next;
                next = temp1;
                return true;
            }
            else
            {
                return false;
            }
        }
        public bool MoveForward(ListElem prev)
        {
            if (prev == null)
            {
                return Program.root.MoveForward();
            }
            else
            {
                if (next != null)
                {
                    prev.next = next;
                    ListElem temp1 = next.next;
                    next.next = this;
                    next = temp1;
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }
        public bool MoveBackward()
        {
            return Program.root.MoveForward();
        }
        public bool MoveBackward(ListElem prev2)
        {
            if (prev2 != null)
            {
                 if (prev2.next != null)
                 {
                    return prev2.next.MoveForward(prev2);
                
                 }
                 else
                 {
                    return false;
                 }
            }
            else
            {
                return Program.root.MoveForward();
            }
        }
    }
}

Warte wyjaśnienia jest tworzenie listy: najpierw tworzymy 2. element (temp2), po czym tworzymy początek i przypisujemy do jego pola next referencję do drugiego obiektu. Dalej w pętli najpierw tworzymy 'następny' element, a potem przypisujemy 'poprzedniemu' referencję do niego, a na końcu 'następny' staje się tym 'poprzednim' i sytuacja się powtarza. W klasie ListElem dodałem metody umożliwiające przesunięcie danego elementu listy, które przydadzą się do sortowania. Move Forward przesuwa dany element do przodu - jednakże, jako że mamy do czynienia z listą jednokierunkową, musimy jej podać również poprzedni element. Jeśli przesuwamy początek listy, jako poprzednik podajemy null lub w ogóle go nie podajemy (przeładowanie). MoveBackward to krótko mówiąc MoveForward dla elementu poprzedniego danemu. W związku z tym musimy mu podać poprzednik poprzednika jako argument (prev2). Jeśli poprzednik poprzednika nie istnieje, podajemy null lub nie podajemy tego argumentu. Początku przesunąć do tyłu nie możemy, więc ten problem odpada. Wszystko to jest dosyć skomplikowane na pierwszy rzut oka, (bo używamy listy jednokierunkowej, i nie mamy dostępu z danego elementu do jego poprzednika), ale na dłuższą metę nie jest to trudne zagadnienie. Jeśli chcesz użyć jakiegoś szybkiego sortowania, np quick sort czy merge sort, to będziesz musiał sobie dopisać metody takie jak zamień, wytnij, wstaw etc, ale jeśli poprzestaniesz np na bąbelkowym, to te które zamieściłem wystarczą. No to chyba wszystko, jak będziesz miał pytania lub coś przeoczyłem w tym kodzie to oczywiście pisz ;)

0

Jestem Ci niesamowicie wdzieczny, ze w ogole chcialo Ci sie cos takiego napisac, mam takie pytanko : jezeli w poleceniu mam "posortowac ta tablice za pomoca listy jednokierunkowej" czy to oznacza ze juz gotowa liste wystarczy posortowac w osobnej klasie nie odnoszac sie do Twojej klasy ListElem i to wystarczy:)?

1

Nie za bardzo rozumiem, co znaczy 'posortować tablicę za pomocą listy' (wrzucić tablicę do listy i posortować?), natomiast jeśli chcesz po prostu posortować listę (jak napisałeś na początku), to do samej klasy podczas sortowania owszem nie musisz się odnosić, natomiast oczywiście musisz odnosić się do obiektów tej klasy.

0

No i w tym wszystkim wlasnie chodzi o to ze nie bardzo wiem jak to zrobic, probowalem z sort. babelkowym, ale nie wiem do jakich fukcji w tej klasie sie odniesc, po kilkugodzinnych staraniach napisalem tutaj , gdyz nie ma nigdzie jakiejs pomocy jak to zrobic a ja sam jak juz wielokrotnie napisalem nie jestem najlepszy w programowaniu, a niedlugo sesja i trzeba zdac;d

1

Sortowanie bąbelkowe polega na zamienianiu dwóch elementów miejscami, jeśli są ułożone w złej kolejności. Do zamiany miejsc możesz użyć np funkcji MoveForward:

if(a.value>b.value)
{
     a.MoveForward();
}

gdzie a i b są obiektami ListElem. W tej sytuacji zakładamy, że dwuelementowa lista ma być posortowana rosnąco, i jest ułożona w kolejności a,b. Jeśli więc a>b, to musimy zamienić je miejscami. Jak wygląda sortowanie bąbelkowe masz przedstawione tu: http://edu.i-lo.tarnow.pl/inf/alg/003_sort/0006.php . Mam nadzieję, że nie wiążesz swojej przyszłości z informatyką, bo to są algorytmy na poziomie liceum...

0

Niestety na to troche za prozno, ogolnie ja wiem jak posortowac zalozmy 10 pseudolosowych liczb, ale zaimplementowac do listy nie mam pojecia jak;p
Wobec tego mam pare pytanek i pomyslow, jezeli zechcesz mi an nie odpisac;
Jezeli dobrze kumam to najpierw musze utworzyc nowa funkcje w klasie ListElem , ktora zalozmy nazwe tak:

 public static void Sort()

Tutaj w nawiasie nie wiem do czego ma sie odnosic ta funkcja?
Domyslam sie(pewnie zle), ze do tego;
(int value, ListElem next, int cnt)
Musi sie odnosic do wartosci, nastepnego elementu oraz rozmiaru tablicy, zeby moc w ogole to zaimplementowac, napisalem cos takiego, wiem ze glupoty i smiech na sali ze nie umiem tak prostych rzeczy, ale gdzies musze sie ich nauczyc, a dzis mam to oddac;/

public static void Sort(int value, ListElem next, int cnt)
        {
            Stopwatch time = new Stopwatch();//pomiar czasu sortowania tablicy
            time.Reset();
            time.Start();
            int size = cnt;
            for (int i = 0; i < size - 1; i++)
            {
                if (a.value > b.value)
                {
                    a.MoveForward();  // Nie mam pojecia co w tym ifie dac i do jakich elementow a i b ma sie odnosic.
                }


            }
            time.Stop();// zatrzymanie pomiaru

            Console.WriteLine(time.Elapsed);//wypisanie pomiaru
        }

 

dodatkowo chce jeszze zmierzyc czas sortowania wiec mysle ze to jedyne dobre miejsce aby je wrzucic

1

Funkcja ma być w klasie programu (w tej gdzie masz metodę Main), za argument ma przyjmować korzeń listy, i ma zawierać pętle, która przelatuje po wszystkich elementach tej listy i sprawdza, czy każde 2 są w odpowiedniej kolejności względem siebie, jeśli nie, to zamienia je miejscami. Dodatkowo musi zawierać semafor (boola) który zmienia wartość jeśli lista jest posortowana. Długość listy Ci nie jest potrzebna, zamiast pętli for użyj while tak jak ja w wyświetlaniu listy. Możesz spróbować napisać sobie funkcję sortującą tablice, a potem ją przerobić. No a co do nauki to jeśli nie nauczyłeś się w szkole ani na wykładzie, to zostają tutoriale w necie i ew książki. No ale to nie na dzień przed zaliczeniem. Co do czasu to możesz go dodać w programie, przed wykonaniem metody i zakończyć po jej wykonaniu, ale na Twoim miejscu zostawiłbym to sobie na koniec

1

to sprawozdanie tylko;d robie zadania na bierzaca, ale nie wiem jakie ty miales standardy w Lo skoro dla ceibie to totakie proste;d .Jak juz wczesniej napisalem dla porownania zrobilem sobie tablice z pseaudolosowymi 10 liczbami, nastepnie przez sortowanie babelkowe ja posortowalem, ale tutaj trzeba to zaimplementowac odwolujac sie do elementow z innej klasy, skad ja wziac jak zrobic ja nie mam pojecia i teoretyczne wytlumaczenie raczej mi nie pomoze, dzieki w kazdym razie za pomoc, poprobuje sobie jeszcze ale raczej odpuszcze sobei to zadanko, dzieki za poswiecony czas i wybacz ze moj poziom programowania jest dla ciebie tak smieszny no ale nie kazdy od razu jest w czyms dobry.

Dzieki jeszcze raz

1 użytkowników online, w tym zalogowanych: 0, gości: 1