انجمن‌های فارسی اوبونتو

لطفاً به انجمن‌ها وارد شده و یا جهت ورود ثبت‌نام نمائید

لطفاً جهت ورود نام کاربری و رمز عبورتان را وارد نمائید

نویسنده موضوع: لیست پیوندی  (دفعات بازدید: 1893 بار)

0 کاربر و 1 مهمان درحال مشاهده موضوع.

آفلاین fond

  • Full Member
  • *
  • ارسال: 144
لیست پیوندی
« : 03 اردیبهشت 1392، 09:53 ق‌ظ »
با سلام

خب من یه چیزهایی رو پاک کردم که خوندن کد راحتتر بشه. هنوز خیلی از توابع رو پیاده سازی نکردم چون هنوز نتوستم تابع ()insert رو بنویسم. این کدی بود که من نوشتم اما اون طور که انتظار دارم کار نمی‌کنه:

تابع ()print قراره لیست رو چاپ کنه. تابع ()addfirst یه چیزی رو به اول لیست اضافه می‌کنه و تابع ()insert یک چیزی رو در یک جای خاص از لیست قرار می‌دهد و تابع ()getnode هم یک node میگیره.

فایل list.h

#include <stdio.h>
#include <stdlib.h>

typedef struct node node;

struct node {
        int value;
        node* next;
};

node *getnode();
void addfirst(node**,int);
void print(node *);
void insert(node **, int, int);

فایل list.c
#include "list.h"


int main()
{
        node *list;

        insert(&list, 0, 5);
        insert(&list, 1, 10);
        insert(&list, 2, 15);
        insert(&list, 3, 20);

        print(list);

        return 0;
}

node *getnode()
{
        node* temp;
        temp = (node*) malloc( sizeof(node) );

        if( temp != NULL )
                return temp;

        abort();
}

void addfirst( node **ptr, int val )
{
        node *temp = getnode();
        temp -> value = val;
        temp -> next = *ptr;
        (*ptr) = temp;
}

void print( node *ptr )
{
        while( ptr )
        {
                printf("%d\n", ptr -> value );
                ptr = ptr -> next;
        }
}

void insert(node **ptr, int index, int val)
{


        if(index == 0)
        {
                addfirst(ptr, val);
        }
        else
        {
                node *temp = getnode();
                temp -> value = val;

                int j;

                for(j=1; j < index; j++)
                {
                        (*ptr) = (*ptr) -> next;
                }

                temp -> next = (*ptr) -> next;
                (*ptr) -> next = temp;
        }

}

خیلی ممنونم
« آخرین ویرایش: 03 اردیبهشت 1392، 10:15 ق‌ظ توسط fond »

آفلاین فاراب

  • High Hero Member
  • *
  • ارسال: 1352
  • آزادی
    • پروفایل لینکداین
پاسخ : لیست پیوندی
« پاسخ #1 : 03 اردیبهشت 1392، 09:58 ق‌ظ »
من نفهمیدم دقیقا مشکل چیه. اما کتاب ساختمان داده‌ها هم کد و هم توضیح رو داره. فکر میکنم اینجوری بهتر باشه. در ضمن کد آماده هم خیلی راحت گیر میاد گوگل کنید. وقتی قبلا نوشته شده چه نیازی به نوشتن مجدد کد هست. . اگر جایی مشکل داشتید بفرمایید.
Godisnowhere

آفلاین fond

  • Full Member
  • *
  • ارسال: 144
پاسخ : لیست پیوندی
« پاسخ #2 : 03 اردیبهشت 1392، 10:07 ق‌ظ »
حقیقتش قصدم فقط یادگیری هست. درسته که قبلا توی کتابخانه stl و همینطور جاهای دیگه پیاده سازی شده اما من فقط هدفم یادگیری هست. من دارم از روی کتاب ساختمان داده‌های هوریتز پیش میرم. از بین اون توابعی که قرار دادم، همگی به جز ()insert کار می‌کنن. برنامه هم اصلا اجرا نمیشه و coredump میشه.

خیلی ممنون که توجه کردید :D

آفلاین فاراب

  • High Hero Member
  • *
  • ارسال: 1352
  • آزادی
    • پروفایل لینکداین
پاسخ : لیست پیوندی
« پاسخ #3 : 03 اردیبهشت 1392، 10:19 ق‌ظ »
لیست پیوندی بیشتر با ++C پیاده میشه. اما شما انگار با C کار میکنید.
کد زیر بصورت کامل تست شده است و بجای insert از enter استفاده میکنه. تمام حقوقش هم متعلق به Sundown از سایت http://barnamenevis.org/ هست. امیدوارم به کارتون بیاد:

/*//////////////////////////////
Structure In C
*///////////////////////////////

#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>     
#include <ctype.h>
#define  TRUE  1
#define NIL (struct Employee *)NULL
struct Employee {
       char name[30] ;
       int ID ;
       char JobTittle[30] ;
   char Addres[30];
       struct Employee *next ;
} ;
struct Employee *first , *last , *node ;
void enter ();
void list ();
void del ();
void FindByID();
int main ()
{   
char  s[10] ;
    first = NIL ;
    while (TRUE) {


     printf("E:\tEnter New Employee\n");

     printf("R:\tRemove a Employee\n");

     printf("L:\tList All Of The Employee\n");

printf("F:\tFind Employee By ID\n");

     printf("Q:\tQuit The Program\n") ;

     printf("Make Your Choice :  ");
     printf("( E R L F Q) :   ") ;
     gets(s) ;
     *s = toupper(*s) ;
     switch (*s) {
   case 'E' :
       enter() ;
       break ;
   case 'L' :
       list() ;        
       break ;
   case 'R' :
       del() ;
       break ;
   case 'F':
   FindByID();
   break;
   case 'Q' :
       exit(0) ;
     }
   }
return 0;
}
//********************
void enter ()
  {
   char numstr[30] ;
   node = (struct Employee *)malloc(sizeof(struct Employee));
   node -> next = NIL ;
   if (first == NIL)
       first = last = node ;
   else  {

   last -> next = node ;

last = node ;
   }
   printf("\n Enter name of Employee:");
   gets(last -> name) ;

   printf("\n Enter Employee ID :");
   gets(numstr) ;
   last -> ID = atoi(numstr) ;

   printf("\n Enter Employee JobTittle :");   
   gets(last -> JobTittle) ;

   printf("\n Enter Addres :");   
   gets(last -> Addres) ;

}
//********************
void list ( )
{
     printf("\n\n\n\n");
int i ;
     if (first == NIL) {
printf("\n<< the list is empty .>>") ;
getch() ;
return ;
     }
     last = first ;


     printf("\t\tName\t\tNumber\t\tJobTittle\tAddres\n");

      printf("\t\t----\t\t------\t\t--------\t---------") ;
      i = 6 ;
  printf("\n\n");
      do {

printf("\t\t");
   printf("%s", last -> name) ;

   printf("\t\t");
   printf("%d", last -> ID) ;

   printf("\t\t");
   printf("%s", last -> JobTittle) ;

   printf("\t\t");
   printf("%s",last -> Addres);
   i ++ ;
   last=last -> next ;
   printf("\n\n");
      } while (last != NIL) ;

  printf("\n\n\n\n");
      printf("\t\t********************************************") ;     

      printf("\npress a key to continue...");  
      getch() ;
  printf("\n\n");
}
//*******************
void del ()
{
    int stnumber ;

    printf("Enter Employee ID for delete:");
    scanf("%d", &stnumber) ;
    last = node = first ;
    while (last != NIL)
    {
     if (last -> ID!=stnumber)  {
  node = last ;
  last = last -> next ;
  continue ;
     }
     else
{
if (last == first)
{
first=last -> next ;
free(last) ;
free(node) ;
break ;
}
else
{
     node -> next=last -> next;
     free(last) ;
break ;
}
     }
    }
}

//*******************
void FindByID()
{
    int stnumber ;
  if (first == NIL) {
printf("\n<< the list is empty .>>") ;
getch() ;
return ;
     }
last = first ;
    printf("\n\nEnter Employee ID To Search It : ");
    scanf("%d", &stnumber) ;
   
  printf("\n\n\t\tName\t\tNumber\t\tJobTittle\tAddres\n");

      printf("\t\t----\t\t------\t\t--------\t---------") ;     
  printf("\n\n");

do
{

if (last -> ID==stnumber)

{
printf("\t\t");
printf("%s", last -> name) ;

printf("\t\t");
printf("%d", last -> ID) ;

printf("\t\t");
printf("%s", last -> JobTittle) ;

printf("\t\t");
printf("%s",last -> Addres);


printf("\n\n");
}
last=last -> next ;
      } while (last != NIL) ;

  printf("\n\n\n\n");
      printf("\t\t********************************************") ;     

      printf("\npress a key to continue...");  
      getch() ;
  printf("\n\n");


}



Godisnowhere

آفلاین کیان

  • High Hero Member
  • *
  • ارسال: 2338
  • جنسیت : پسر
پاسخ : لیست پیوندی
« پاسخ #4 : 03 اردیبهشت 1392، 11:20 ق‌ظ »
جزییات بیشتری به عنوان تاپیک اضافه کن!

آفلاین fond

  • Full Member
  • *
  • ارسال: 144
پاسخ : لیست پیوندی
« پاسخ #5 : 03 اردیبهشت 1392، 11:55 ق‌ظ »
خیلی ممنون به خاطر اون برنامه. توی ++c با کلاسها میشه خیلی راحت لیست رو پیاده سازی کرد. حتی یه پیاده سازی از لیست دو طرفه هم توی کتابخانه stl وجود داره.

اون برنامه به نظر من چند تا اشکال داره:

اول اینکه اون برنامه از متغیرهای سراسری استفاده می‌کنه که این خوب نیست. بهتره اطلاعات رو از طریق پارامترها به توابع بفرستیم که کد پرتابل تر بشه و اشکالزدایی هم راحت‌تر بشه (تا جایی که ممکنه نباید از متغیر سراسری استفاده کرد)
دوم اینکه اون برنامه طوری نوشته شده که بتونه با کاربر به صورت تعاملی رفتار کنه. اما معمولا لیست پیوندی باید توسط برنامه نویس استفاده بشه.

من تابع ()insert رو بدین صورت بازنویسی کردم و همه چیز درست شد:
void insert(node **head, int index, int val)
{
        node *ptr = (*head);

        if(index == 0)
        {
                addfirst(head, val);
        }
        else
        {
                node *temp = getnode();
                temp -> value = val;

                int j;

                for(j=1; j < index; j++)
                {
                        ptr = ptr -> next;
                }

                temp -> next = ptr -> next;
                ptr -> next = temp;
        }
   
}


آفلاین فاراب

  • High Hero Member
  • *
  • ارسال: 1352
  • آزادی
    • پروفایل لینکداین
پاسخ : لیست پیوندی
« پاسخ #6 : 03 اردیبهشت 1392، 12:58 ب‌ظ »
خیلی ممنون به خاطر اون برنامه. توی ++c با کلاسها میشه خیلی راحت لیست رو پیاده سازی کرد. حتی یه پیاده سازی از لیست دو طرفه هم توی کتابخانه stl وجود داره.

اون برنامه به نظر من چند تا اشکال داره:

اول اینکه اون برنامه از متغیرهای سراسری استفاده می‌کنه که این خوب نیست. بهتره اطلاعات رو از طریق پارامترها به توابع بفرستیم که کد پرتابل تر بشه و اشکالزدایی هم راحت‌تر بشه (تا جایی که ممکنه نباید از متغیر سراسری استفاده کرد)
دوم اینکه اون برنامه طوری نوشته شده که بتونه با کاربر به صورت تعاملی رفتار کنه. اما معمولا لیست پیوندی باید توسط برنامه نویس استفاده بشه.

من تابع ()insert رو بدین صورت بازنویسی کردم و همه چیز درست شد:
void insert(node **head, int index, int val)
{
        node *ptr = (*head);

        if(index == 0)
        {
                addfirst(head, val);
        }
        else
        {
                node *temp = getnode();
                temp -> value = val;

                int j;

                for(j=1; j < index; j++)
                {
                        ptr = ptr -> next;
                }

                temp -> next = ptr -> next;
                ptr -> next = temp;
        }
   
}

کاملا درسته. امیدوارم همیشه توی برنامه نویسی موفق باشید.
Godisnowhere

آفلاین fond

  • Full Member
  • *
  • ارسال: 144
پاسخ : لیست پیوندی
« پاسخ #7 : 04 اردیبهشت 1392، 05:58 ب‌ظ »
خب نسخه تقریبا کامل شدش رو اینجا میذارم تا شاید بدرد دوستان دیگه هم بخوره. البته این بیشتر شبیه یه شبه کده و خوب باید خودتون تغییرش بدید.

#include <stdio.h>
#include <stdlib.h>

typedef struct node node;

struct node {
        int value;
        node* next;
};

node *getnode();
void addfirst(node**, int);
int getfirst(node**);
void print(node *);
int get(node*, int);
void deletelist(node**);
void insert(node **, int, int);
void del(node **, int);
int search(node *, int val);



node *
getnode()
{
node* temp;
temp = (node*) malloc( sizeof(node) );

if( temp != NULL )
{
temp -> next = NULL;
return temp;
}

exit(EXIT_FAILURE);
}

void
addfirst( node **ptr,
int val )
{
node *temp = getnode();
temp -> value = val;
temp -> next = *ptr;

(*ptr) = temp;

}

int
getfirst(node **ptr)
{
node *temp = *ptr;
*ptr = (*ptr) -> next;

free(*ptr);

return temp -> value;
}

void
print( node *ptr )
{
while( ptr )
{
printf("%d\n", ptr -> value );
ptr = ptr -> next;
}
}

int
get(node *head,
int i)
{
        node *ptr = head;

        while( --i )
        {
                ptr = ptr -> next;
        }
   
        return (ptr -> value);
}


void
deletelist( node **head )
{
        node *ptr = *head;
node *next;

        while( ptr )
        {
next = ptr -> next;
free(ptr);
ptr = next;
        }
}

void
insert(node **head,
int index,
int val)
{
node *ptr = (*head);

if(index == 0)
{
addfirst(head, val);
}

else
{
node *temp = getnode();
temp -> value = val;

int j;

for(j=1; j < index; j++)
{
ptr = ptr -> next;
}


temp -> next = ptr -> next;
ptr -> next = temp;

}

}


void
del( node **head,
int index )
{

if( index == 0 )
{
node *ptr = (*head);

(*head) = ptr -> next;

free(ptr);

}

else
{
node *preptr = (*head);
node *ptr = preptr -> next;

int j;

for(j=1; j < index; j++)
{
preptr = preptr -> next;
ptr = preptr -> next;
}

preptr -> next = ptr -> next;

free(ptr);

}


}

int
search(node *head,
int val)
{
int i = 0;

node *ptr = head;

while( ptr )
{
if( (ptr -> value) == val )
return i;
i++;

ptr = ptr -> next;
}

return (-1);
}

آفلاین fond

  • Full Member
  • *
  • ارسال: 144
پاسخ : لیست پیوندی
« پاسخ #8 : 04 اردیبهشت 1392، 06:15 ب‌ظ »
شاید بهتر باشه یه توضیح مختصری هم بدم. هر چند برنامه سادست و قابل فهمه اما خوب شاید این توضیحات برای دوستانی که قصد یادگیری دارند مناسب باشه:

این عمل یه لیست خالی ایجاد می‌کنه:

node *list1 = getnode()
این عمل هم یه مقدار جدید رو به ابتدای لیست اضافه می‌کنه (همون push):

void addfirst(node **head, int value);

اولین عنصر لیست رو برمیگردونه و بعدش اونو از لیست حذف می‌کنه (همون pop):

int getfirst(node **head);

 لیست رو چاپ می‌کنه:

void print(node *head);
یه عنصر رو از هر جای دلخواهی از لیست بازیابی می‌کنه اما اون رو حذف نمیکنه:

int get(node *head, int index);
که index اندیس همون عنصری هست که می‌خوایم بازیابی بشه.

لیست رو کامل حذف می‌کنه:

void deletelist(node **head);
یه عنصری رو به هر جای لیست اضافه می‌کنه:

void insert(node **head, int index, int val);
که index مکانی هست که می‌خوایم val اضافه بشه.

این یکی هم یه عنصر رو از هر جای لیست حذف می‌کنه:

void del(node **head, int index);
برای جستجوی یک مقدار در لیست:

int search(node *head, int val);
اگر اشکالی داره خواهش می‌کنم بهم بگید تا تصحیح کنم.

آفلاین vandu

  • Hero Member
  • *
  • ارسال: 741
  • جنسیت : پسر
پاسخ : لیست پیوندی
« پاسخ #9 : 04 اردیبهشت 1392، 07:01 ب‌ظ »
ممنون. کد کاملی شده. فقط فکر می‌کنم در تابع get توی شرط حلقه بجای ‎--i‎ باید نوشته بشه ‎i--‎ . چون اندیس‌ها از صفر شروع میشن. البته اگه اشتباه نکنم...
Nothing is particularly hard if you divide it into small jobs

Henry Ford

آفلاین fond

  • Full Member
  • *
  • ارسال: 144
پاسخ : لیست پیوندی
« پاسخ #10 : 04 اردیبهشت 1392، 07:27 ب‌ظ »
بله حق با شماست. الان تست کردم متوجه شدم تابع ()print هم یه صفر اضافه چاپ می‌کنه.