الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

جدول محقق بواسطة لائحة مترابطة

بدأه yahya91 في 28 مايو 2011 · 4 رد · 428 مشاهدة · في الأسئلة المجابة
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم

لدي الكود التالي الذي هو تحقبق لجدول table باستخدام لئحة مترابطة و ذلك دون استخدام توابع hash على فرض أنه يتم إدخال key من المستخدم و فيه التوابع التالية :

*تابع insert لإدخال حد جديد (سوف أعتبر أن إضافة العقدة node الجديدة من النهاية )

*تابع remove لحذف عقدة عبر الkey المُمرر كوسيط (آلية الحذف التي اتبعتها عي نسخط قيمة عقدة نهاية اللائحة إلى موضع الحذف ثم حذف الذيل tail )

*تابع lookup للتأكد من وجود حد يحتوي على كيمة key ممررة و من ثم يسند في حال تحقق ذلك قيمة data العقدة إلى الوسيط data

*تابع dump للطباعة .

*تابع search بحث عن حد مطلوب و يتوقف بمؤشر kptr قبله إن وُجد و إلا سوف يعيد 0 (فكرة التوقف قبل الحد المطلوب بمؤشر هي ستلزمني عن الحذف إذا لا بد ريط العقدة السابقة بالعقدة التي تسبق العقدة المطلوبة )

ملاحظة على الأغلب المشكلة لإي تابع search و ذلك بعد تحليلي للمشكلة و لكن لم أعرف ما هو موطن الخطأ .

الكود:

#include<iostream>
using namespace std;
typedef int tkt;
typedef int tdt;
class table{
      private:
              struct node;
              typedef node* link;
              struct node{
                     link next;
                     tkt key;//table key type
                     tdt data;//table data type
                     };
               link tail,head,current;
               int search_t(tkt key,link kptr)//kptr point to key
               {
                   link pred=head;
                   while(pred->next!=0&&pred->next->key!=key)
                   pred=pred->next;
                   kptr=pred;
                   if(kptr->next==0)//not found
                   return 0;
                   else
                   return kptr->next->key;
                   }

                   public:
                          table(){head=tail=current=0;}
                          void insert(tkt insertkey,tdt data)
                          {
                               link addednode=new node;
                               addednode->data=data;
                               addednode->key=insertkey;
                               if(head==0)
                               {addednode->next=0;tail=head=addednode;}
                               else
                               {
                                   link kptr;
                                   int pos=search_t(insertkey,kptr);
                                   if(pos==0)//not found
                                   {head->next=addednode;
                                   addednode->next=0;
                                   tail=addednode;
                                   }
                                   else//update value of data if key is duplicated 
                                   {
                                      kptr->next->data=data; 
                                       }
                               }
                               } 
                             bool lookup(tkt lookupkey,tdt &data)
                             {
                                  link kptr;
                                  int pos=search_t(lookupkey,kptr);
                                  if(pos==0)
                                  return false;
                                  else
                                  data=kptr->next->data;
                                  return true ;
                                  }
                               void remove(tkt delkey)
                               {
                                   link kptr;
                                  int pos=search_t(delkey,kptr); 
                                  if(pos==0)
                                  return;
                                  else
                                  {
                                  tail=kptr;
                                  delete tail->next;
                                  tail->next=0;
                                  }
                                    }  
                                 void dump()
                                  {
                                      link pred=head;
                   cout<<"key"<<"\t"<<"data"<<endl;    
                   while(pred->next!=0)
                   {
                   cout<<pred->key<<"\t"<<pred->data<<endl;                    
                   pred=pred->next;  }
                   }
                   };
                      int main()
                    {
                        table T;int data;
                        T.insert(1,5);
                        T.insert(2,3);

                        T.insert(3,0);

                         T.insert(100,100);

                        T.lookup(1,data);
                       // T.remove(3);
                        cout<<data<<endl;
                        T.dump();
                        int quit;//press any key to continue
                        cin>>quit;
                        return 0;
                        }

تم تعديل هذه المشاركة بواسطة yahya91 في 28 مايو 2011 في 18:36

#2

هل الفئه Table هي Linked List أم Hash Table؟

مدونتي: C++ Tips and Tricks

#3

من حيث المبدأ نعم إلا أنه فقط يتضمن فكرة تخزين ألkey ضمن خانة في عقدة ضمن لائحة أي دون استخدام توابع probing و توابع hash .<br>فقط يهمني فكرة تمثيل جدول كلائحة .

تم تعديل هذه المشاركة بواسطة yahya91 في 29 مايو 2011 في 22:31

#4

قمت بكتابة نسخه من الفئه Table بإستخدام Sorted Doubly Linked List و الترتيب فيها يكون بإستخدام الـ Key - لأنه Integer، أيضا لأننا نحاكي hash table منعت تكرار الـ key، بالنسبه للدوال الموجوده بها فهي كالتالي:

* الداله Insert: لإضافة عنصر جديد، تعيد true إذا تمت الإضافه، و false إذا كان الـ key موجود من قبل.

* الداله Remove: لحذف عنصر موجود، تعيد true إذا تم الحذف و false إذا كان الـ key غير موجود.

* الداله GetValue: للحصول على قيمة key معين، فى حال عدم وجود الـ key يتم رمي الإستثناء invalid_argument.

* الداله KeyExist: للتحقق من وجود key، تعيد true إذا كان موجود و false إذا كان غير موجود.

* الداله GetCount: تعيد عدد العناصر التى تم إضافتها داخل الـ table.

class Table
{
public:
	Table() : mFirst(NULL), mLast(NULL), mCount(0) {}

	bool Insert(int Key, int Value)
	{
		if (KeyExist(Key)) return false;

		TableItem* prev = mLast;
		TableItem* next = NULL;

		// if list is not empty
		if (prev)
		{
			// while last key greater than input index
			while(prev->mKey > Key)
			{
				// save current item
				next = prev;
				// get previous
				prev = prev->mPrevious;
				if (prev == NULL) break;
			}
		}

		TableItem* item = new TableItem(next, prev, Key, Value);

		// if next is null then update last item
		if (!next) mLast = item;
		// if previous is null then update first item
		if (!prev) mFirst = item;

		mCount++;

		return true;
	}

	bool Remove(int Key)
	{
		TableItem* item = GetItem(Key);

		if (!item) return false;

		item->Remove();

		if (mFirst == item) mFirst = mFirst->mNext;
		if (mLast == item) mLast = mLast->mPrevious;

		mCount--;

		delete item;

		return true;
	}

	int GetValue(int key)
	{
		TableItem* item = GetItem(key);

		if (!item) throw new invalid_argument("input key isn't exist.");

		return item->mValue;
	}

	bool KeyExist(int key) { return GetItem(key) != NULL; }

	int GetCount() const { return mCount; }

private:
	struct TableItem 
	{
		TableItem* mNext;
		TableItem* mPrevious;
		int mKey, mValue;

		TableItem(TableItem* Next, TableItem* Previous, int Key, int Value)
			: mNext(Next), mPrevious(Previous), mKey(Key), mValue(Value) {}

		void Remove()
		{
			if (mNext) mNext->mPrevious = mPrevious;
			if (mPrevious) mPrevious->mNext = mNext;
		}

	} *mFirst, *mLast;

	int mCount;

	TableItem* GetItem(int key)
	{
		TableItem* item = mFirst;

		while ( item )
		{
			if (item->mKey == key) return item;

			item = item->mNext;
		}

		return NULL;
	}
};

و الله ولي التوفيق

1

مدونتي: C++ Tips and Tricks

#5

شكراً جزيلا لك أخي محمد علاء و جزاك الله خيراً . طبعاً حلك للمشكلة أكثر فاعلية و أسهل كونك استخدمت لائحة مضاعفة الترابط و هذا ينهي مشكلة التابع search في حلي و لكن طلب الكتاب التقيد بلائحة عادية (احادية الترابط )لذلك كنت مجبر ان أوجد مؤشر يعيد لي المكان الذي قبل مكان تواجد الkey عبر المؤشر kptr .

ولكن الحمد لله وجدت المشكلة و كانت في التابع الإدخال و هي كالتالي :

...
if(pos==0)//not found
                           		{tail->next=addednode;//كنت واضع head->next=addednode 
                           		addednode->next=0;
                           		tail=addednode;
                           		}
...

تم تعديل هذه المشاركة بواسطة yahya91 في 30 مايو 2011 في 13:56

1

مواضيع مشابهة