You are on page 1of 83

‫هياكل بيانات وخوارزميات‬

‫)‪(Data Structures and Algorithms‬‬


‫عملي‬

‫اعـــــــــــداد وتجميـــــع‪:‬‬

‫م‪ .‬ماجــد البعداني‬


‫المحتوى‬
Lab.1: Review about 1-D and 2-D arrays …………………………………………………………. 1

Lab.2: Review about pointers and structures.………………………………………………………. 5

Lab.3: Stacks…...……………………………………………………………………………………. 16

Lab.4: Stack applications and Queues ………….………………………………………………….. 22

Lab.5: Linked Lists(I)…………………………………………………...…………………………... 30

Lab.6: Linked Lists (II)…………………………………………………….…………………………38

Lab.7: Doubly Linked Lists & stack and Queue using Linked List………………………………… 49

Lab.8: Trees (I)…………………………………………….………………………………………... 61

Lab.9: Trees (II): Follow Binary Search Tree……………………………...……………………….. 67

Lab.10: Graphs. ……………………………………………………………………………………...73


‫ ماجد البعداني‬/.‫م‬ lab.1: Arrays (1-D and 2-D) -‫عملي‬-‫هياكل بيانات وخوارزميات‬

❖ Objectives:
- Revision about functions in C++
- To be able to deal with 1-D and 2-D arrays (input to and print them)
- To be able to pass 1-D and 2-D arrays to functions.
❖ Examples:
1- Write a program to input an integer array of size of 50 with n elements and do the following:
a- Search about the even numbers in the array
b- Sort the array in ascending order.
➢ The C++ Code:
#include<iostream>
#include<stdio.h>
#include<conio.h>
using namespace std;

/* Function decleration */
void search(int [],int); // Function to saerch about the even numbers
void sort(int [],int); // Function to sort the array
void printing(int [],int); // Function to print the array elements
const int Max_Size=100;
main()
{
int A[Max_Size],n,i;
cout<<" Enter the No. of elements:";
cin>>n;
cout<<" Enter the elemetns to the array:"<<endl;
for (i=0; i<n; i++)
cin>>A[i];
cout<<" The Entered array is:"<<'\n';
printing(A,n);
cout<<"the even numbers are in locations: ";
search(A,n);
cout<<endl<<"the array after sorting in ascending order is :"<<endl;
sort(A,n);
printing(A,n);
}
/* Functions definition */
void search(int A[],int n){
for(int i=0;i<n;i++)

1
‫ ماجد البعداني‬/.‫م‬ lab.1: Arrays (1-D and 2-D) -‫عملي‬-‫هياكل بيانات وخوارزميات‬

if(A[i]%2==0)
cout<<i<<" ";
}
void sort(int A[],int n)
{
int temp,i,j;
for(i=0;i<n-1;i++)
for(j=i+1;j<n;j++)
if(A[j]<A[i])
{
temp=A[i];
A[i]=A[j];
A[j]=temp;
}
}
void printing (int A[],int n)
{
for (int i=0; i<n; i++)
cout<<"A["<<i<<"]="<<A[i]<<endl;
}

2- Write a C++ program to define an integer matrix of size 100×100 with n×m elements then find the
largest element in each row and in each column in the matrix.
➢ The C++ Code:
#include<iostream>
#include<stdio.h>
#include<conio.h>
using namespace std;
const int max_row=50;
const int max_col=50;
/* Function decleration */
void printing(int [][max_col],int,int); // Function to print the matrix
void larg_row(int [][max_col],int,int); // Function to find the largest
element in each row
void larg_col(int [][max_col],int,int); // Function to find the largest
element in each row

2
‫ ماجد البعداني‬/.‫م‬ lab.1: Arrays (1-D and 2-D) -‫عملي‬-‫هياكل بيانات وخوارزميات‬

main()
{
int A[max_row][max_col],i,j,n,m;
cout<<"enter the number of rows: ";
cin>>n;
cout<<"enter the number of columns: ";
cin>>m;
cout<<"enter the elements of the matrix :"<<endl;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
cin>>A[i][j];
cout<<"the matrix is: \n";
printing(A,n,m);
cout<<" the largest element in each row are: "<<endl;
larg_row(A,n,m);
cout<<endl<<" the largest element in each column are: "<<endl;
larg_col(A,n,m);
}
/* Functions definition */
void printing(int A[][max_col],int n,int m)
{
int i,j;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
cout<<A[i][j]<<" ";
cout<<endl;
}
}
void larg_row(int A[][max_col],int n,int m)
{
int i,j,max;
for( i=0;i<n;i++)
{
max=A[i][0];
for (j=1;j<m;j++)
if(A[i][j]>max)
max=A[i][j];

3
‫ ماجد البعداني‬/.‫م‬ lab.1: Arrays (1-D and 2-D) -‫عملي‬-‫هياكل بيانات وخوارزميات‬
cout<<"the max of row "<<i+1<<"="<<max<<endl;
}
}
void larg_col(int A[][max_col],int n,int m)
{
int i,j,max;
for( i=0;i<m;i++)
{
max=A[0][i];
for (j=1;j<n;j++)
if(A[j][i]>max)
max=A[j][i];
cout<<"the max of col "<<i+1<<"="<<max<<endl;
}
}

Home Work 1:
✓ Write a program to input an integer array of size of 100 with n elements and calculate the
summation of the prime numbers in it?
✓ Write a C++ program to define an integer matrix of size 50×50 with n×m elements then find
the summation of the elements in each row.
‫ قم باستخدام الدوال إلجابه السؤالين السابقين‬:‫✓ مالحظة‬

4
‫ ماجد البعداني‬/.‫م‬ lab.2: Review about Pointers and Structures -‫عملي‬-‫هياكل بيانات وخوارزميات‬

The computer memory is a sequential collection of storage cells as shown in Figure (1). Each cell commonly
known as a byte, has a number called address associated with it. Typically, the addresses are numbered
consecutively, starting from zero. The last address depends on the memory size. A computer system having 64 k
memory will have its last address as 65,535.
Address
Memory Cell

65,535

Figure (1): Memory Organization.

• If we declare an integer variable as follow:

int quantity=159;

the system will allocate location for this variable and puts the value 159 in that location. Assuming that the
address location is 5000, we can represent this as shown in Figure (2).

quantity variable

159 value

5000 address

Figure (2): Representation of a variable.

We can access to value 159 either by the name quantity or the address 5000. Since the memory addresses
are simply numbers, they can be assigned to some variables called pointer variables.

5
‫ ماجد البعداني‬/.‫م‬ lab.2: Review about Pointers and Structures -‫عملي‬-‫هياكل بيانات وخوارزميات‬
Variable value address

quantity 159 5000

p 5000 5084

Pointers: Are variables that store address of other variables.

❖ Accessing the Address of a Variable:

We can return the address of a variable with the help of the operator & available in C++.

P=& quantity;

P will contain the address of the variable quantity in the memory (i.e. 5000).

Ex:

main( ) {
int x=10;
char a='A';
cout<<x<<" is stored at location "<<&x;
cout<<a<<"is stored at location "<<&a;
}
❖ Declaring of Initializing Pointer Variables:

Syntax:

data_type *pointer_name;

EX:

int x;
int *p;
p=&x;

❖ Accessing a Variable Through its Pointer:


It is done by the * (artistic) operator (also known as dereferencing operator).
Main( ) {
int x, *p, n;
x=50;
p=&x;
n=*p; \\ n will be 50

6
‫ ماجد البعداني‬/.‫م‬ lab.2: Review about Pointers and Structures -‫عملي‬-‫هياكل بيانات وخوارزميات‬
cout<<"value of n : "<<n<<'\n';
cout<<"value of x before : " <<x;
*p= 100; \\ the value of x will change to 100
cout<<" value of x after : "<< x;
}
The * operator can be remembered as " value at address".

Pointers and Functions


❖ As we know that a user-defined function can return just one value using the return statement. If we want to
return multiple values from one function, we must use the concept of pointers as explained in the lecture.
• Example:
Write a C++ program that finds MAX and MIN elements of an array with max size 100 and n number
of elements using the pointer concept (i.e., one function to compute MAX and MIN values and return
them at the same time)
1- Using call by pointer:

#include<iostream>

#include<conio.h>

using namespace std;

const int MAX_Size= 100;

void MAX_MIN (int x[ ], int *p, int *s, int n){

/* p is a pointer to MAX variable( i.e. take the address of MAX variable),

s is a pointer to MIN variable( i.e. take the address of MIN variable) */

int i;

for (i=1;i<=n; i++){

if (x[i]>*p)

*p=x[i]; // *p means value at address p

if (x[i]<*s)

*s=x[i]; // *s means value at address s

}}

main( ){

int Array[MAX_Size], MAX, MIN, n;

7
‫ ماجد البعداني‬/.‫م‬ lab.2: Review about Pointers and Structures -‫عملي‬-‫هياكل بيانات وخوارزميات‬
cout<<"Enter the number of elements n= ";

cin>>n;

cout<<"Enter the elements of the array"<<'\n';

for (int i=1;i<=n; i++)

cin>>Array[i];

/* initializing the MAX and MIN values with the first element in the array */

MAX=Array[1];

MIN=Array[1];

/* calling the function of MAX_MIN*/

MAX_MIN (Array, &MAX, &MIN, n);

cout<<" the max value is :" <<MAX<<endl;

cout<<" the min value is :" <<MIN<<endl;

getch( );

2- Using call by pointer:


#include<iostream>
#include<conio.h>
using namespace std;
const int MAX_Size= 100;
void MAX_MIN (int x[ ], int &p, int &s, int n){
/* p is a reference to MAX variable( i.e. take the address of MAX variable),
s is a reference to MIN variable( i.e. take the address of MIN variable) */
int i;
for (i=1;i<=n; i++){
if (x[i]> p)
p=x[i];
if (x[i]< s)
s=x[i];
}}

8
‫ ماجد البعداني‬/.‫م‬ lab.2: Review about Pointers and Structures -‫عملي‬-‫هياكل بيانات وخوارزميات‬
main( ){
int Array[MAX_Size], MAX, MIN, n;
cout<<"Enter the number of elements n= ";
cin>>n;
cout<<"Enter the elements of the array"<<'\n';
for (int i=1;i<=n; i++)
cin>>Array[i];
/* initializing the MAX and MIN values with the first element in the array */
MAX=Array[1];
MIN=Array[1];
/* calling the function of MAX_MIN*/
MAX_MIN (Array, MAX, MIN, n);
cout<<" the max value is :" <<MAX<<endl;
cout<<" the min value is :" <<MIN<<endl;
getch();
}
Structures
Consider a book database consisting of book name, author, number of pages and price. We can define a
structure to hold this information as follow:
struct book
{
char title[20];
char author[15];
int pages;
float price;
};
• Declaring Structure Variables:
A structure variable declaration is similar to the declaration of any other data type. It includes the following
elements:
1- The structure tag name.
2- List of variable names separated by commas.
3- A terminating semicolon.

9
‫ ماجد البعداني‬/.‫م‬ lab.2: Review about Pointers and Structures -‫عملي‬-‫هياكل بيانات وخوارزميات‬

EX:
book book1,book2,book3;
• Accessing the Structure Members:
There are two ways to access the members of a structure variable:
1- Using the Dot '.' Notation:
Example:

struct Employee
{
char name[20];
char department[30];
float salary;
};
main( ) {
Employee Person1,Person2;
cout<<"Enter the values of the first structure variable"<<'\n';
cin>>Person1.name>>Person1.department>>Person1.salary;
cout<<"Enter the values of the second structure variable"<<'\n';
cin>>Person2.name>>Person2.department>>Person2.salary;
cout<<"the stored valuse"<<endl;
cout<< Person1.name<<'\t'<<Person1.department<<'\t'<<Person1.salary;
cout<< Person2.name<<'\t'<<Person2.department<<'\t'<<Person2.salary;
getch();
}

2- Using the Pointer Concept:


This can be done by defining a pointer variable of type structure and assigning the address of the
structure variable to it. Two notations can be used:
(*ptr). member_name;
ptr-> member_name;
where ptr is a pointer to the structure variable. following example illustrates this concept.
Example:
struct Employee
{

10
‫ ماجد البعداني‬/.‫م‬ lab.2: Review about Pointers and Structures -‫عملي‬-‫هياكل بيانات وخوارزميات‬
char name[20];
char department[30];
float salary;
};
main( ) {
Employee Person1, *ptr;
ptr=&Person1;
cout<<"Enter the values of the second structure variable"<<'\n';
cin>>(*ptr). name>> (*ptr). department>>(*ptr). salary;
cout<<"the values of the structure variable are"<<'\n';
cout<<ptr-> Name<<'\t'<< ptr-> Department<< '\t'<< ptr-> salary;
getch( );
}

Structures and Functions


The structure variable can be passed into a function by two ways:
1- By reference: Any change in the structure members within the function are reflected in the original
structure.
2- By name: Any change in the structure members within the function are not reflected in the original
structure.

Example
❖ write a C++ program to define a structure Class of three members: name, an array of three subjects and grade
then do the following:
1- Create tow structure variables student1 and student2.
2- Create a function to input the name and marks of subjects for the two students.
3- Create a function to input the grade as follow:
A if average of of the marks >=90
B if 80=<average<90
C if 65=<average<80
F if average<65
4-Create a function to print the values of members for the two students
❖ The program:
/* 1- by using pointer */
#include<iostream>
using namespace std;
struct Class{

11
‫ ماجد البعداني‬/.‫م‬ lab.2: Review about Pointers and Structures -‫عملي‬-‫هياكل بيانات وخوارزميات‬
string name;
int sub[5];
char grade;
};
void input_name_sub(Class *);
void input_grade(Class *);
void print(Class );
main(){
Class student1,student2;
cout<<"enter name and marks of subjects for the first student:"<<endl;
input_name_sub(&student1);
cout<<"enter name and marks of subjects for the second student:"<<endl;
input_name_sub(&student2);
/* assigning the grade for the students using input grade function */
input_grade(&student1);
input_grade(&student2);
cout<<endl<<"-------------output----------------"<<endl;
cout<<"first student:"<<endl;
print(student1);
cout<<"second student:"<<endl;
print(student2);
}
void input_name_sub(Class *p){
cout<<"name:";
cin>>p->name;
cout<<"marks:";
for(int i=0;i<5;i++)
cin>>p->sub[i];
}
void input_grade(Class *p){
int sum=0;
double avg;
for (int i=0;i<5;i++)
sum=sum+p->sub[i];
avg=sum/5;
if (avg>=90)
p->grade='A';

12
‫ ماجد البعداني‬/.‫م‬ lab.2: Review about Pointers and Structures -‫عملي‬-‫هياكل بيانات وخوارزميات‬
else if (avg>=80 )
p->grade='B';
else if (avg>=65)
p->grade='C';
else
p->grade='F';
}
void print(Class student){
cout<<"name:"<<student.name<<'\n';
cout<<"marks:" ;
for (int i=0;i<5;i++)
cout<<student.sub[i]<<" ";
cout<<endl<<"grade:"<<student.grade<<'\n'; }
/* 2- by using reference */
#include<iostream>
using namespace std;
struct Class{
string name;
int sub[5];
char grade;
};
void input_name_sub(Class &);
void input_grade(Class &);
void print(Class );
main(){
Class student1,student2;
cout<<"enter name and marks of subjects for the first student:"<<endl;
input_name_sub(student1);
cout<<"enter name and marks of subjects for the second student:"<<endl;
input_name_sub(student2);
/* assigning the grade for the students using input grade function */
input_grade(student1);
input_grade(student2);
cout<<endl<<"-------------output----------------"<<endl;
cout<<"first student:"<<endl;
print(student1);
cout<<"second student:"<<endl;

13
‫ ماجد البعداني‬/.‫م‬ lab.2: Review about Pointers and Structures -‫عملي‬-‫هياكل بيانات وخوارزميات‬
print(student2);
}
void input_name_sub(Class &p){
cout<<"name:";
cin>>p.name;
cout<<"marks:";
for(int i=0;i<5;i++)
cin>>p.sub[i];
}
void input_grade(Class &p){
int sum=0;
double avg;
for (int i=0;i<5;i++)
sum=sum+p.sub[i];
avg=sum/5;
if (avg>=90)
p.grade='A';
else if (avg>=80 )
p.grade='B';
else if (avg>=65)
p.grade='C';
else
p.grade='F';
}
void print(Class student){
cout<<"name:"<<student.name<<'\n';
cout<<"marks:" ;
for (int i=0;i<5;i++)
cout<<student.sub[i]<<" ";
cout<<endl<<"grade:"<<student.grade<<'\n';
}

14
‫م‪ /.‬ماجد البعداني‬ ‫‪lab.2: Review about Pointers and Structures‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫‪15‬‬
‫م‪ /.‬ماجد البعداني‬ ‫‪lab.3: stacks‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫❖ ما هو ال ‪STACK‬؟‬
‫‪ -‬نوع من أنواع هياكل البيانات حيث يتم فيه تخزين البيانات بترتيب معاكس لترتيب استعادتها (سحبها)‪ ،‬أي أن آخر قيمة يتم إدخالها‬
‫(دفعها) إلى ال ‪ Stack‬هي أول قيمة يتم سحبها من المكدس‪ ،‬وتدعى هذه االلية ‪.)last in first out( LIFO‬‬
‫‪ -‬الحذف واإلضافة تتم من طرف واحد فقط يدعى ‪.)Top Of Stack( TOS‬‬
‫‪ -‬ينفذ ال ‪ STACK‬مجموعة من العمليات األساسية وهي‪:‬‬
‫‪ Push -‬دفع البيانات إلى المكدس‪.‬‬
‫‪ Pop‬سحب البيانات من المكدس‪.‬‬ ‫‪-‬‬
‫‪ IsFull -‬التحقق من ان المكدس ممتلئ‪.‬‬
‫‪ IsEmpty -‬التحقق من ان المكدس فارغ‪.‬‬
‫‪ -‬يمكن بناء ال ‪ Stack‬باستخدام‪:‬‬
‫‪ -1‬المصفوفات (ِ‪.)Arrays based implementation‬‬
‫‪ -2‬القوائم المترابطة (‪.)Linked Lists based implementation‬‬

‫‪Array-based implementation‬‬
‫❖ اإلضافة )‪: PUSH(x‬‬

‫• عند القيام بعملية اإلضافة ال بد من فحص المصفوفة هل هي ممتلئة أم ال‪.‬‬


‫• ثم يتم تنفيذ الخطوات التالية إلضافة العنصر ‪ X‬للمكدس‪:‬‬
‫اضافه العنصر للمكدس عن طريق ال ‪TOS‬‬ ‫‪-‬‬
‫‪S[TOS]=x‬‬
‫زيادة ال ‪ TOS‬بمقدار واحد‬ ‫‪-‬‬
‫‪TOS++‬‬

‫‪TOS=0 \\ empty stack‬‬


‫;]‪int S[5‬‬

‫]‪S[0‬‬ ‫]‪S[1‬‬ ‫]‪S[2‬‬ ‫]‪S[3‬‬ ‫]‪S[4‬‬

‫‪ -‬هنا الحجم األقصى للمكدس (‪ )MaxSize‬هو ‪5‬‬

‫)‪1- Push(6‬‬ ‫)‪2-Push(20‬‬


‫‪TOS = 1‬‬ ‫‪TOS = 2‬‬

‫‪6‬‬ ‫‪6‬‬ ‫‪20‬‬

‫)‪3-Push(10‬‬
‫‪TOS = 3‬‬

‫‪6‬‬ ‫‪20‬‬ ‫‪10‬‬

‫• مالحظة‪ :‬نتوقف عنما يصبح ال ‪ STACK‬ممتلئ (بمعنى عندما تكون قيمه ال ‪ TOS‬تساوي الحجم األقصى (‪.))MaxSize‬‬

‫‪16‬‬
‫م‪ /.‬ماجد البعداني‬ ‫‪lab.3: stacks‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫❖ الحذف )(‪: x= pop‬‬


‫• قبل الحذف ال بد من فحص المصفوفة فيما إذا ما كانت فارغة او ال‪.‬‬
‫• ثم يتم تنفيذ الخطوات التالية لحذف عنصر من المكدس‪:‬‬
‫تنقيص ال ‪ TOS‬بمقدار واحد‬ ‫‪-‬‬
‫‪TOS--‬‬
‫اخذ العنصر من المكدس عن طريق ال ‪ TOS‬واسناده لمتغير وليكن ‪X‬‬ ‫‪-‬‬
‫]‪X= S[TOS‬‬

‫‪2-X= pop() X=20‬‬


‫‪1- X= pop() X=10‬‬
‫‪TOS = 1‬‬
‫‪TOS = 2‬‬
‫‪6‬‬ ‫‪20‬‬ ‫‪6‬‬

‫)(‪3- X= pop‬‬ ‫‪X=6‬‬


‫‪TOS = 0‬‬

‫• مالحظة‪ :‬نتوقف عنما يصبح ال ‪ STACK‬فارغ (بمعنى عندما تكون قيمه ال ‪ TOS‬تساوي صفر)‪.‬‬

‫❖ الكود المستخدم لتصميم المكدس بجميع عملياته األساسية‪:‬‬


‫>‪#include<iostream‬‬
‫;‪using namespace std‬‬
‫‪struct stackType‬‬
‫{‬
‫;‪int MaxStackSize‬‬
‫;‪int TOS‬‬
‫;‪int *list‬‬
‫;}‬
‫)‪void initializeStack (stackType &current,int maxSize‬‬
‫{‬
‫;‪current.MaxStackSize=maxSize‬‬
‫;‪current.TOS=0‬‬
‫;]‪current.list=new int[maxSize‬‬
‫}‬

‫‪17‬‬
‫ ماجد البعداني‬/.‫م‬ lab.3: stacks -‫عملي‬-‫هياكل بيانات وخوارزميات‬

bool isEmpty(stackType current)


{
return (current.TOS==0);
}
bool isFull(stackType current)
{
return(current.TOS==current.MaxStackSize);
}
void push(stackType &current,int element)
{
if(!isFull(current))
{
current.list[current.TOS]=element;
current.TOS++;
}
else
cout<<"the stack is full"<<endl;
}
int pop(stackType &current)
{ int x;
if(!isEmpty(current))
{
current.TOS--;
x=current.list[current.TOS];
return x;
}
else
cout<<"the stack is empty";
}
void print(stackType curr)
{
while(!isEmpty(curr))
cout<<pop(curr)<<" ";
cout<<"\n";
}

18
‫ ماجد البعداني‬/.‫م‬ lab.3: stacks -‫عملي‬-‫هياكل بيانات وخوارزميات‬

main()
{

stackType stack;
int n;
cout<<"enter the maxsize of the stack: ";
cin>>n;
initializeStack(stack,n);
push(stack,20);print(stack);
push(stack,15);print(stack);
push(stack,500);print(stack);
push(stack,-20);print(stack);
int x;
x=pop(stack);
cout<<"the poped element is: "<<x<<endl;
print(stack);
x=pop(stack);
cout<<"the poped element is: "<<x<<endl;
print(stack);
x=pop(stack);
cout<<"the poped element is: "<<x<<endl;
print(stack);
x=pop(stack);
}

‫تطبيق بسيط الستخدام المكدس‬


palindrome ‫ يطلب من المستخدم ادخال نص معين ثم يقوم بفحص النص فيما اذا كان يُقرأ من الجهتين‬C++ ‫• قم بكتابة برنامجا َ بلغة‬

.Stack ‫ تُقرأ من الجهتين بنفس الشكل) مستخدما َ ال‬madam :‫(مثال‬

#include<iostream>
#include<string>
using namespace std;
struct stackType
{
int MaxStackSize;
int TOS;

19
‫ ماجد البعداني‬/.‫م‬ lab.3: stacks -‫عملي‬-‫هياكل بيانات وخوارزميات‬

char *list;
};

void initializeStack (stackType &current,int maxSize)


{
current.MaxStackSize=maxSize;
current.TOS=0;
current.list=new char[maxSize];
}
bool isEmpty(stackType current)
{
return (current.TOS==0);
}
bool isFull(stackType current)
{
return(current.TOS==current.MaxStackSize);
}
void push(stackType &current,char element)
{
if(!isFull(current))
{
current.list[current.TOS]=element;
current.TOS++;
}
else
cout<<"the stack is full"<<endl;
}
char pop(stackType &current)
{ char x;
if(!isEmpty(current))
{
current.TOS--;
x=current.list[current.TOS];
return x;
}
else

20
‫ ماجد البعداني‬/.‫م‬ lab.3: stacks -‫عملي‬-‫هياكل بيانات وخوارزميات‬

cout<<"the stack is empty";


}

main()
{
stackType stack;
initializeStack(stack,30);
string original,reversed="";

cout<<"the string to test for palindrome: ";


cin>>original;
int length=original.length();
for (int i=0;i<length;i++)
{
push(stack,original[i]);
}
while(!isEmpty(stack))
{
reversed=reversed+pop(stack);
}
if(reversed==original)
cout<<"the string: "<<original<<" is planidrome";
}

21
‫م‪ /.‬ماجد البعداني‬ ‫‪lab.4: Queues‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫❖ ما هو ال ‪Queue‬؟‬
‫‪ -‬نوع من أنواع هياكل البيانات حيث يتم فيه تخزين البيانات بحيث يتم استعادتها حسب ترتيب ورودها فالقيمة التي تُخزن اوالَ تتم‬
‫استعادتها أوال‪ .‬وتدعى هذه االلية ‪.)First in first out( FIFO‬‬
‫‪ -‬الحذف واإلضافة تتم من طرفين مختلفين حيث تتم عمليه اإلضافة عن طريق طرف يسمى (‪ )Rear‬والحذف عن طريق طرف يسمى‬
‫(‪.)Front‬‬
‫‪ -‬ينفذ ال ‪ Queue‬مجموعة من العمليات األساسية وهي‪:‬‬
‫‪ Enqueue -‬اضافه بيانات الى ال ‪.Queue‬‬
‫‪ Dequeue‬سحب بيانات من ال ‪.Queue‬‬ ‫‪-‬‬
‫‪ IsFull -‬التحقق من ان الطابور ممتلئ‪.‬‬
‫‪ IsEmpty -‬التحقق من ان الطابور فارغ‪.‬‬
‫‪ -‬يمكن بناء ال ‪ Queue‬باستخدام‪:‬‬
‫‪ -1‬المصفوفات (ِ‪.)Arrays based implementation‬‬
‫‪ -2‬القوائم المترابطة (‪.)Linked Lists based implementation‬‬
‫هناك نوعين من الطوابير‪:‬‬ ‫‪-‬‬
‫‪ -1‬الطابور الخطي (‪)Linear Queue‬‬
‫‪ -2‬الطابور الدائري (‪)Circular Queue‬‬

‫‪Array-based implementation‬‬
‫لنفرض ان لدينا ‪ Queue‬بحجم اقصى (‪ )maxsize‬وليكن ‪ 4‬كما هو موضح بالشكل التالي‪:‬‬
‫‪ -‬يكون ال ‪ Queue‬في حالته االبتدائية عندما يكون ‪ rear=-1‬و‪( front=0‬حسب افتراضنا نحن)‬

‫‪rear=-1 Front=0‬‬
‫]‪int Q[4‬‬

‫‪0‬‬ ‫‪1‬‬ ‫‪2‬‬ ‫‪3‬‬

‫‪ -‬وبهذا تكون الخطوات الالزمة إلضافة عنصر وليكن ‪ x‬للطابور )‪ Enqueue(x‬هي‪:‬‬


‫‪ -1‬زيادة ال ‪ rear‬بمقدار واحد‪:‬‬
‫‪rear ++‬‬
‫‪ -2‬اضافه العنصر للطابور عن طريق ال ‪:rear‬‬
‫‪Q[rear]=x‬‬
‫سنقوم االن بإدخال ثالثة عناصر للطابور كما هو مبين في االشكال التالية‪:‬‬

‫‪rear=0‬‬ ‫‪rear=1‬‬
‫‪Front=0‬‬ ‫‪Front=0‬‬
‫)‪1- Enqueue(8‬‬ ‫)‪2- Enqueue(10‬‬
‫‪8‬‬ ‫‪8‬‬ ‫‪10‬‬
‫‪0‬‬ ‫‪1‬‬ ‫‪2‬‬ ‫‪3‬‬ ‫‪0‬‬ ‫‪1‬‬ ‫‪2‬‬ ‫‪3‬‬

‫‪22‬‬
‫م‪ /.‬ماجد البعداني‬ ‫‪lab.4: Queues‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫‪rear=0‬‬
‫‪Front=0‬‬
‫)‪3- Enqueue(-5‬‬
‫‪8‬‬ ‫‪10‬‬ ‫‪-5‬‬
‫‪0‬‬ ‫‪1‬‬ ‫‪2‬‬ ‫‪3‬‬
‫✓ مالحظة‪ :‬يكون الطابور ممتلئ في حالة كان ‪rear=mazsize-1‬‬

‫‪ -‬وتكون الخطوات الالزمة لحذف عنصر من الطابور )(‪( x=dequeue‬حيث ان ‪ x‬هي القيمة المحذوفة من الطابور) هي ‪:‬‬
‫‪ -1‬اخذ العنصر من الطابور عن طريق ال ‪:front‬‬
‫]‪X=Q[front‬‬
‫‪ -2‬زيادة ال ‪ front‬بمقدار واحد‬
‫‪Front++‬‬
‫سنقوم االن بحذف عنصرين من الطابور كما هو مبين في االشكال التالية‪:‬‬

‫‪rear=2‬‬ ‫‪rear=2‬‬
‫‪Front=1‬‬ ‫‪Front=2‬‬
‫‪4- x= Dequeue()=8‬‬ ‫‪5- x= Dequeue()=10‬‬
‫‪10‬‬ ‫‪-5‬‬ ‫‪-5‬‬
‫‪0‬‬ ‫‪1‬‬ ‫‪2‬‬ ‫‪3‬‬ ‫‪0‬‬ ‫‪1‬‬ ‫‪2‬‬ ‫‪3‬‬

‫✓ مالحظة‪ :‬يكون الطابور فارغ في حالة كان ‪front=rear+1‬‬


‫االن لو قمنا بإضافة عنصر للطابور سوف يُملئ الموقع الرابع في الطابور كما يلي‪:‬‬
‫‪rear=3‬‬
‫‪Front=2‬‬
‫)‪6- Enqueue(20‬‬
‫‪-5‬‬ ‫‪20‬‬
‫‪0‬‬ ‫‪1‬‬ ‫‪2‬‬ ‫‪3‬‬
‫لو أردنا االن اضافه عنصر جديد لن تتم عملية اإلضافة بسبب ان الطابور أصبح ممتلئا حسب الشرط بالرغم من ان هناك موقعين‬
‫فارغين في الطابور كما في الشكل لهذا نحتاج الطابور الدائري الستغالل هذه المساحة وهو ما سيتم التطرق اليه في الصفحات التالية‪.‬‬

‫الطابور الدائري (‪)Circular Queue‬‬


‫‪ -‬كي نجعل الطابور دائريا سوف نقوم بتغيير معادلتي ال ‪ front‬وال ‪ rear‬بحيث نستطيع االنتقال للموقع ‪ 0‬بمجرد وصولنا للموقع‬
‫األخير(‪ )maxsize-1‬في الطابور‪.‬‬
‫‪ -‬مالحظة‪ :‬لفحص الطابور فيما إذا كان ممتلئا او فارغا سوف نقوم بإضافة متغير جديد وليكن ‪ count‬قيمته االبتدائية هي ‪ .0‬كلما‬
‫اضفنا عنصرا للطابور نزيد قيمته بمقدار واحد وكلما حذفنا عنصرا من الطابور ننقص قيمته بمقدار واحد‪ .‬طبقا لهذا الحل يكون‬
‫الطابور ممتلئا اذا كان ‪ count=maxsize‬ويكون فارغا اذا كان ‪. count=0‬‬
‫‪ -‬وبهذا تكون الخطوات الالزمة إلضافة عنصر للطابور الدائري هي‪:‬‬
‫‪ -1‬فحص فيما اذا كان الطابور ممتلئا أوال‪.‬‬
‫‪rear=(rear+1) %maxsize -2‬‬

‫‪23‬‬
‫م‪ /.‬ماجد البعداني‬ ‫‪lab.4: Queues‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫‪Count ++ -4‬‬ ‫‪Q[rear]=x -3‬‬


‫‪ -‬والخطوات اللزمة لحذف عنصر من الطابور الدائري هي‪:‬‬
‫‪ -1‬فحص فيما اذا كان الطابور فارغا أوال‪.‬‬
‫‪x=Q[front] -2‬‬
‫‪front=(front+1) %maxsize -3‬‬
‫‪Count – -4‬‬
‫‪ -‬فيما يلي توضيح لهذه العمليات‪:‬‬
‫‪3‬‬

‫‪Count=0‬‬

‫‪Count=1‬‬ ‫‪Count=2‬‬ ‫‪Count=3‬‬ ‫‪Count=2‬‬ ‫‪Count=1‬‬ ‫‪Count=2‬‬

‫‪Count=3‬‬ ‫‪Count=4‬‬ ‫‪Count=5‬‬ ‫‪Count=4‬‬

‫❖ الكود المستخدم لتصميم الطابور الدائري بجميع عملياته األساسية‪:‬‬


‫>‪#include<iostream‬‬
‫;‪using namespace std‬‬
‫{‪struct queueType‬‬
‫;‪int maxQueueSize‬‬
‫;‪int count‬‬

‫‪24‬‬
‫ ماجد البعداني‬/.‫م‬ lab.4: Queues -‫عملي‬-‫هياكل بيانات وخوارزميات‬

int Front;
int Rear;
int *list;
};
void initializeQueue(queueType &curr,int max)
{
curr.Front=0;
curr.Rear=-1;
curr.count=0;
curr.maxQueueSize=max;
curr.list=new int[max];
}
bool isEmpty(queueType &curr)
{
return (curr.count==0);
}
bool isFull(queueType &curr)
{
return (curr.count==curr.maxQueueSize);
}
void addQueue(queueType &curr,int x)
{
if(isFull(curr)==false)
{
curr.Rear=(curr.Rear+1)%curr.maxQueueSize;
curr.count++;
curr.list[curr.Rear]=x;
}
else
cout<<"Full Queue";
}
int deleteQueue(queueType &curr)
{
if(!isEmpty(curr))
{

25
‫ ماجد البعداني‬/.‫م‬ lab.4: Queues -‫عملي‬-‫هياكل بيانات وخوارزميات‬

int x=curr.list[curr.Front];
curr.Front=(curr.Front+1)%curr.maxQueueSize;
curr.count--;
return x;
}
else
{
cout<<"empty Queue";
return 0;
}
}
void print(queueType curr)
{
cout<<"queue elements: ";
while(!isEmpty(curr))
{
cout<<deleteQueue(curr)<<" ";
}
cout<<endl;
}
main( ){
queueType queue;
initializeQueue(queue,10);
int x,n;
cout<<"enter the number of element to add into queue: ";
cin>>n;
for(int i=0;i<n;i++){
cin>>x;
addQueue(queue,x);}
print(queue);
cout<<"the deleted element: "<<deleteQueue(queue)<<endl;
print(queue);
cout<<"the deleted element: "<<deleteQueue(queue)<<endl;
print(queue);
}

26
‫م‪ /.‬ماجد البعداني‬ ‫‪lab.4: Queues‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫تطبيق اخر للمكدس‬


‫‪ -‬قم بكتابة برنامج يطلب من المستخدم ادخال رقم عشري (‪ )Decimal‬ثم باستخدام المكدس اكتب داله لتحويل الرقم العشري الى رقم ثنائي‪.‬‬

‫✓ البرنامج المستخدم لحل السؤال السابق‪:‬‬


‫>‪#include<iostream‬‬
‫;‪using namespace std‬‬
‫‪struct stackType‬‬
‫{‬
‫;‪int MaxStackSize‬‬
‫;‪int TOS‬‬
‫;‪int *list‬‬
‫;}‬
‫)‪void initializeStack (stackType &current,int maxSize‬‬
‫{‬
‫;‪current.MaxStackSize=maxSize‬‬
‫;‪current.TOS=0‬‬

‫‪27‬‬
‫ ماجد البعداني‬/.‫م‬ lab.4: Queues -‫عملي‬-‫هياكل بيانات وخوارزميات‬

current.list=new int[maxSize];
}
bool isEmpty(stackType current)
{
return (current.TOS==0);
}
bool isFull(stackType current) {
return(current.TOS==current.MaxStackSize);
}

void push(stackType &current,int element)


{
if(!isFull(current))
{
current.list[current.TOS]=element;
current.TOS++;
}
else
cout<<"the stack is full"<<endl;
}
int pop(stackType &current)
{ int x;
if(!isEmpty(current))
{
current.TOS--;
x=current.list[current.TOS];
return x;
}
else
cout<<"the stack is empty";
}
/* ‫*داله لتحويل الرقم العشري الى ثنائي باستخدام المكدس‬/

28
‫ ماجد البعداني‬/.‫م‬ lab.4: Queues -‫عملي‬-‫هياكل بيانات وخوارزميات‬

void Decimal_To_Binary(int num)


{
int rem;
stackType stack;
initializeStack(stack,15);
while(num!=0)
{
rem=num%2;
push(stack,rem);
num=num/2; }

while(!isEmpty(stack))
cout<<pop(stack);
}
main()
{
int num;
cout<<"Enter the decimal number: "<<endl;
cin>>num;
cout<<"the equivalent binary number is :" <<endl;
Decimal_To_Binary(num);
}

29
‫م‪ /.‬ماجد البعداني‬ ‫)‪lab.5: Linked Lists(I‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫❖ القوائم المترابطة (‪:)Linked Lists‬‬

‫‪ -1‬عبارة عن مجموعة من العناصر(السجالت) تُدعي العُقد(‪ .)nodes‬يتم تخزين هذه العناصر في الذاكرة بشكل غير متجاور‬
‫(هذا عكس المصفوفات حيث يتم تخزين البيانات في الذاكرة بشكل متتالي (متجاور))‪.‬‬
‫‪ -2‬كل عقدة (‪ )node‬تتكون على األقل من حقلين‪ .‬حقل البيانات لتخزين البيانات (‪ )data‬وحقل العنوان (‪)address‬‬
‫لتخزين عنوان العقدة التالية‪.‬‬
‫‪ -3‬عنوان العقدة األولى في القائمة المترابطة يُخزن دائما ً في متغير منفصل (هذا المتغير من نوع مؤشر) يسمى ب ‪head‬‬

‫‪ -4‬إذا كانت قيمة ال ‪ head‬تساوي ‪ ،NULL‬هذا يعني ان القائمة فارغه‪.‬‬

‫‪ -5‬حقل العنوان للعقدة األخيرة دائما تكون قيمته تساوي ‪.NULL‬‬


‫✓ الشكل التالي يوضع ما تم ذكره باألعلى‪:‬‬

‫‪200‬‬ ‫‪300‬‬ ‫‪1500‬‬ ‫‪500‬‬


‫‪head‬‬ ‫‪200‬‬ ‫‪45‬‬ ‫‪300‬‬ ‫‪-90‬‬ ‫‪1500‬‬ ‫‪20‬‬ ‫‪500‬‬ ‫‪30‬‬ ‫‪NULL‬‬
‫‪data link‬‬ ‫‪data link‬‬ ‫‪data link‬‬ ‫‪data link‬‬

‫‪ -‬الن كل عقدة في القائمة المترابطة تحتوي على حقلين‪ ،‬نحتاج تعريف كل عقدة كسجل (‪ )structure‬كما يلي‪:‬‬
‫{‪struct Node‬‬
‫;‪int data‬‬ ‫حقل البيانات ‪//‬‬
‫; ‪Node *link‬‬ ‫حقل العنوان(مؤشر للعقدة التالية) ‪//‬‬
‫;}‬
‫;‪Node *head‬‬ ‫مؤشر ألول عقدة في القائمة ‪//‬‬
‫‪ -‬اعتمادا على الشكل السابق‪ ،‬الجدول التالي يوضح قيم ال ‪ head‬وبعض العقد الموجودة في القائمة المترابطة‪:‬‬
‫توضيح‬ ‫القيمة‬

‫‪200‬‬ ‫‪head‬‬

‫الن قيمة ال ‪ head‬هي ‪ 200‬وال ‪ data‬للعقدة الموجودة في الموقع‬


‫‪45‬‬ ‫‪head->data‬‬
‫‪ 200‬هي ‪45‬‬

‫‪300‬‬ ‫‪head->link‬‬

‫الن قيمة ال ‪ head->link‬هي ‪ 300‬وال ‪ data‬للعقدة الموجودة في‬


‫‪-90‬‬ ‫‪head->link->data‬‬
‫الموقع ‪ 300‬هي ‪-90‬‬

‫‪30‬‬
‫م‪ /.‬ماجد البعداني‬ ‫)‪lab.5: Linked Lists(I‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫❖ العمليات الرئيسية الممكن تطبيقها على القائمة المترابطة هي‪:‬‬


‫‪ -1‬إضافة عقدة (‪ )insertion a node‬للقائمة المترابطة‪:‬‬
‫في بداية القائمة‪.‬‬ ‫‪-‬‬
‫في نهاية القائمة‪.‬‬ ‫‪-‬‬
‫في موقع معين في القائمة‪.‬‬ ‫‪-‬‬
‫‪ -2‬حذف عقدة (‪ )deletion of a node‬من القائمة المترابطة‪:‬‬
‫من بداية القائمة‪.‬‬ ‫‪-‬‬
‫من نهاية القائمة‪.‬‬ ‫‪-‬‬
‫من موقع معين في القائمة‪.‬‬ ‫‪-‬‬
‫‪ -3‬المرور بجميع العقد في القائمة (‪ )traversing‬اما لطباعة العناصر او للبحث عن عنصر معين او إلجراء عمليات أخرى‬
‫على العناصر الموجودة في القائمة‪.‬‬

‫‪ -1‬إضافة عقدة في بداية القائمة المترابطة‪:‬‬


‫لنفرض ان لدينا القائمة المترابطة التالية‪:‬‬
‫‪200‬‬ ‫‪300‬‬ ‫‪500‬‬
‫‪200‬‬ ‫‪45‬‬ ‫‪300‬‬ ‫‪-90‬‬ ‫‪500‬‬ ‫‪30‬‬ ‫‪NULL‬‬

‫الخطوات الالزمة إلضافة عقدة في البداية )‪ inserting _beginning (x‬هي‪:‬‬


‫أ‪ -‬تكوين عقدة جديدة باستخدام معامل ‪ new‬كما يلي‪:‬‬
‫;)( ‪Node *Temp =new Node‬‬
‫هنا سوف تتكون عقدة جديدة في الذاكرة (مكونه من حقلين ‪ data‬و‪ ،)link‬عنوان هذه العقدة سوف يُسند للمؤشر ‪Temp‬‬

‫‪130‬‬

‫‪Temp‬‬ ‫‪130‬‬
‫‪data‬‬ ‫‪link‬‬

‫ب‪ -‬ادخال القيمة ‪( x‬ولتكن مثال ‪ )100‬لحقل البيانات (‪ )data‬في العقدة‪:‬‬


‫;‪Temp -> data= x‬‬
‫‪130‬‬

‫‪Temp‬‬ ‫‪130‬‬
‫‪100‬‬
‫‪data‬‬ ‫‪link‬‬
‫ت‪ -‬اسناد العنوان الموجود في ال ‪ head‬لحقل العنوان (‪ )link‬في العقدة الجديدة‪.‬‬
‫;‪Temp -> link= head‬‬
‫ث‪ -‬نجعل ال ‪ head‬يشير للعقدة الجديدة وذلك بإسناد قيمة ال ‪ Temp‬الى ال ‪head‬‬
‫;‪head= Temp‬‬

‫‪31‬‬
‫م‪ /.‬ماجد البعداني‬ ‫)‪lab.5: Linked Lists(I‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫بعد اإلضافة سوف تصبح القائمة المتصلة بالشكل التالي‪:‬‬


‫‪130‬‬ ‫‪200‬‬ ‫‪300‬‬ ‫‪500‬‬
‫‪130‬‬ ‫‪0100‬‬ ‫‪200‬‬ ‫‪45‬‬ ‫‪300‬‬ ‫‪-90‬‬ ‫‪500‬‬ ‫‪30‬‬ ‫‪NULL‬‬
‫‪0‬‬

‫{)‪void inserting _beginning (int x‬‬


‫‪Node *Temp= new Node( ); /* creation of new node */‬‬
‫;‪Temp -> data= x‬‬
‫;‪Temp ->link=head‬‬
‫;‪head=Temp‬‬
‫}‬
‫‪ -2‬إضافة عقدة في نهاية القائمة المترابطة‪:‬‬
‫الخطوات الالزمة إلضافة عقدة في النهاية )‪ inserting _end (x‬هي‪:‬‬
‫أ‪ -‬تكوين عقدة جديدة باستخدام معامل ‪ new‬كما يلي‪:‬‬
‫;) ( ‪Node *Temp =new Node‬‬
‫‪250‬‬

‫‪Temp‬‬ ‫‪250‬‬
‫‪data‬‬ ‫‪link‬‬
‫ب‪ -‬ادخال القيمة ‪( x‬ولتكن مثال ‪ )50‬لحقل البيانات (‪ )data‬في العقدة الجديدة وقيمة ‪ NULL‬لحقل العنوان (ألنها ستكون‬
‫اخر عقدة)‪:‬‬
‫;‪Temp ->data= x‬‬
‫;‪Temp -> Link= NULL‬‬

‫‪250‬‬

‫‪Temp‬‬ ‫‪250‬‬ ‫‪50‬‬ ‫‪NULL‬‬


‫‪data‬‬ ‫‪link‬‬
‫ت‪ -‬نقوم بالمرور على العُقد (نبدأ من ال ‪ )head‬عن طريق استخدام حلقه تكرارية حتى نصل الى اخر عقدة في القائمة ثم‬

‫نقوم بإسناد قيمة ال ‪( Temp‬عنوان العقدة الجديدة) لحقل العنوان الخاص باخر عقدة في القائمة وبالتالي تصبح العقدة‬
‫األخيرة مشيرة للعقدة الجديدة وبالتالي تُصبح العقدة الجديدة هي األخيرة في القائمة‪.‬‬

‫; ‪Node *Temp2=head‬‬
‫{)‪while (Temp2 -> link != NULL‬‬
‫} ;‪Temp2= Temp2 -> link‬‬
‫‪Temp2 -> link= Temp‬‬

‫ث‪ -‬إذا كانت القائمة فارغه (‪ ،)head=NULL‬نقوم بإسناد عنوان العقدة الجديدة (‪ )Temp‬الى ‪ head‬بشكل مباشر‪.‬‬
‫;‪head=Temp‬‬

‫‪32‬‬
‫م‪ /.‬ماجد البعداني‬ ‫)‪lab.5: Linked Lists(I‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫وبالتالي يكون شكل القائمة بعد اإلضافة كما يلي‪:‬‬

‫‪130‬‬ ‫‪200‬‬ ‫‪300‬‬ ‫‪500‬‬ ‫‪250‬‬


‫‪130‬‬ ‫‪0100‬‬ ‫‪200‬‬ ‫‪45‬‬ ‫‪300‬‬ ‫‪-90‬‬ ‫‪500‬‬ ‫‪30‬‬ ‫‪250‬‬ ‫‪50‬‬ ‫‪NULL‬‬
‫‪0‬‬

‫{ )‪void Inserting _End (int x‬‬


‫;) ( ‪struct Node *Temp= new Node‬‬
‫;‪Temp ->data= x‬‬
‫;‪Temp -> Link= NULL‬‬
‫)‪if(head==NULL‬‬
‫;‪head=Temp‬‬
‫{‪else‬‬
‫; ‪struct Node *Temp2=head‬‬
‫{)‪while (Temp2 -> link != NULL‬‬
‫} ;‪Temp2= Temp2 -> link‬‬
‫};‪Temp2 -> link= Temp‬‬
‫}‬
‫‪ -3‬إضافة عقدة في مكان محدد في القائمة المترابطة‪:‬‬
‫اعتمادا ً على القائمة المترابطة السابقة‪ ،‬وبفرض المكان المراد إضافة العقدة الجديدة فيه هو ‪ pos=2‬والقيمة ال ُمراد اضافتها‬
‫هي ‪55‬‬
‫الخطوات الالزمة لإلضافة هي‪:‬‬
‫أ‪ -‬انشاء عقدة جديدة واسناد القيمة لحقل البيانات كما يلي‪:‬‬
‫;) ( ‪Node *Temp =new Node‬‬
‫;‪Temp ->data= x‬‬

‫‪400‬‬
‫‪Temp‬‬ ‫‪400‬‬ ‫‪55‬‬
‫‪data‬‬ ‫‪link‬‬

‫ب‪ -‬التحرك بحلقة تكرارية حتى الوصول للعقدة التي تسبق المكان المراد إضافة العقدة الجديدة فيه (حسب افتراضنا نريد‬
‫الوصول للعقدة ‪ ،)1‬ثم نقوم بعمل الخطوتين التاليتين‪:‬‬
‫‪ -‬اسناد العنوان الموجود في العقدة التي وصلنا اليها (هنا ‪ )1‬لحقل العنوان الموجود في العقدة الجديدة‪.‬‬
‫‪ -‬اسناد عنوان العقدة الجديدة (‪ )Temp‬لحقل العنوان للعقدة التي وصلنا اليها‪.‬‬
‫ت‪ -‬إذا كان المكان المراد إضافة العقدة اليه هو ‪ 1‬فإننا نقوم باستدعاء داله اإلضافة في البداية‪.‬‬

‫{) ‪void Inserting _ Position ( int x, int pos‬‬


‫;) ( ‪struct Node *Temp= new Node‬‬

‫‪33‬‬
‫ ماجد البعداني‬/.‫م‬ lab.5: Linked Lists(I) -‫عملي‬-‫هياكل بيانات وخوارزميات‬

Temp ->data= x;
if (pos==1)
inserting _beginning (x);
else {
struct Node *Temp2=head;
for (i=1;i<pos-1;i++)
Temp2=Temp2 -> link;
Temp -> link=Temp2 ->link;
Temp2 -> link =Temp;
}

130 200 300 500 250


130 0
100 400 45 300 -90 500 30 250 50 NULL
0

400
55 200
data link

:-‫ طباعة عناصر القائمة‬-)traversing( ‫ عملية المرور بجميع العُقد‬-4


void print ( )
{
struct Node *Temp=head;
cout<<" The list is: " ;
while (Temp!=NULL) {
cout<<Temp->data ;
Temp= Temp -> link;
}
cout<<endl;
}

:‫❖ كتابة البرنامج كامالً الختبار صحة ما تم عمله باألعلى‬


#include<iostream>
#include<conio.h>
using namespace std;
struct Node{

34
‫ ماجد البعداني‬/.‫م‬ lab.5: Linked Lists(I) -‫عملي‬-‫هياكل بيانات وخوارزميات‬

int data;
Node *link ;
};
Node *head;
void inserting_beginning (int x){
Node *Temp= new Node(); /* creation of new node */
Temp->data= x;
Temp->link=head;
head=Temp;
}
void print ( )
{
Node *Temp=head;
cout<<" The list is: " ;
while (Temp!=NULL) {
cout<<Temp->data<<" " ;
Temp= Temp->link;
}
cout<<endl ;
}
void Inserting_End(int x) {
Node *Temp= new Node ();
Temp->data= x;
Temp->link= NULL;
if(head==NULL)
head=Temp;
else
{
Node *Temp2=head ;
while (Temp2 -> link != NULL){
Temp2= Temp2->link;
}
Temp2->link=Temp;
}
}

35
‫ ماجد البعداني‬/.‫م‬ lab.5: Linked Lists(I) -‫عملي‬-‫هياكل بيانات وخوارزميات‬

void Inserting_Position (int x,int pos){


Node *Temp= new Node ( );
Temp ->data= x;
if (pos==1)
inserting_beginning (x);
else{
Node *Temp2=head;
for (int i=1;i<pos-1;i++)
Temp2=Temp2 -> link;
Temp->link=Temp2 ->link;
Temp2->link =Temp;
}}
main (){
int ch,x;
head=NULL; // Empty linked list
cout <<"enter 1 to add node at beginning"<<endl;
cout <<"enter 2 to add node at the end"<<endl;
cout<< "enter 3 to add node at nth position"<<endl;
cout<<"enter 4 to print the list"<<endl;
cout<<"enter 0 to exit" <<endl;
cout<<"_______________________________________________________"<<endl;
do {
cin>>ch;
if (ch==1){
cout<<"enter element:";
cin>>x;
inserting_beginning (x);
}
if (ch==2){
cout<<"enter element:";
cin>>x;
Inserting_End(x);
}
if (ch==3){
cout<<"enter element:";

36
‫ ماجد البعداني‬/.‫م‬ lab.5: Linked Lists(I) -‫عملي‬-‫هياكل بيانات وخوارزميات‬

cin>>x;
int pos;
cout<<" enter the position :";
cin>>pos;
Inserting_Position(x,pos);
}
if (ch==4){
print();
}
}while (ch != 0);
getch();
}

37
‫م‪ /.‬ماجد البعداني‬ ‫)‪lab.6: Linked Lists (II‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫❖ حذف عقدة (‪ )deletion of a node‬من القائمة المترابطة‪:‬‬


‫من بداية القائمة‪.‬‬ ‫‪-‬‬
‫من موقع معين في القائمة (شامالً الحذف من النهاية)‪.‬‬ ‫‪-‬‬

‫‪ -1‬حذف عقدة من بداية القائمة المترابطة‪:‬‬


‫لنفرض ان لدينا القائمة المترابطة التالية‪:‬‬
‫‪130‬‬ ‫‪200‬‬ ‫‪300‬‬ ‫‪500‬‬
‫‪130‬‬ ‫‪0100‬‬ ‫‪200‬‬ ‫‪45‬‬ ‫‪300‬‬ ‫‪-90‬‬ ‫‪500‬‬ ‫‪30‬‬ ‫‪NULL‬‬
‫‪0‬‬

‫الخطوات الالزمة لحذف عقدة من البداية )( ‪ x=Deleting _beginning‬هي‪:‬‬


‫أ‪ -‬فحص فيما إذا كانت القائمة فارغه ام ال‪.‬‬
‫ب‪ -‬اسناد قيمة ال ‪ head‬لمتغير وليكن ‪( Temp‬بحيث يصبح مؤشرا ألول عقدة في القائمة)‬
‫;‪Node *Temp=head‬‬
‫ت‪ -‬جعل ال ‪ head‬يشير للعقدة الثانية بدالً من األولى (هنا تم حذف العقدة من القائمة لكنها لم تُحذف فعليا ً من الذاكرة‪.‬‬
‫;‪Head=Temp->link‬‬
‫ث‪ -‬اسناد العنصر المحذوف لمتغير وليكن ‪X‬‬
‫;‪x=Temp->data‬‬
‫ج‪ -‬حذف العقدة األولى فعليا ً من الذاكرة عن طريق ال ‪Temp‬‬

‫;‪delete Temp‬‬
‫يُصبح شكل القائمة بعد حذف العقدة األولى كالتالي‪:‬‬

‫‪200‬‬ ‫‪300‬‬ ‫‪500‬‬


‫‪200‬‬ ‫‪45‬‬ ‫‪300‬‬ ‫‪-90‬‬ ‫‪500‬‬ ‫‪30‬‬ ‫‪NULL‬‬

‫‪int‬‬ ‫{ ) ( ‪Deleting_begining‬‬
‫)‪if (head==NULL‬‬
‫;"‪cout<<"Empty List‬‬
‫‪else‬‬
‫{‬
‫;‪Node *Temp=head‬‬
‫;‪int x=Temp -> data‬‬
‫;‪head = Temp->link‬‬
‫}};‪return x‬‬

‫‪38‬‬
‫م‪ /.‬ماجد البعداني‬ ‫)‪lab.6: Linked Lists (II‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫‪ -2‬حذف عقدة من مكان معين في القائمة المترابطة‪:‬‬


‫الخطوات الالزمة لحذف عقدة من مكان معين )‪ x=Deleting _position (pos‬هي‪:‬‬
‫لنفرض اننا نريد حذف العقدة الثالثة من القائمة المترابطة الموجودة في األعلى‪:‬‬
‫أ‪ -‬فحص فيما إذا كانت القائمة فارغة أوال‪.‬‬
‫ب‪ -‬يجب او ًال ان ننتقل للعقدة السابقة للعقدة المراد حذفها كالتالي‪:‬‬
‫;‪Temp=head‬‬
‫)‪For(int i=1;i<pos-1;i++‬‬
‫;‪Temp=Temp->Link‬‬
‫ت‪ -‬تعريف متغير وليكن ‪ Temp2‬بحيث يصبح مؤشرا ً للعقدة ال ُمراد حذفها‬
‫;‪Node *Temp2=Temp->link‬‬

‫‪130‬‬ ‫‪200‬‬ ‫‪300‬‬ ‫‪500‬‬


‫‪130‬‬ ‫‪0100‬‬ ‫‪200‬‬ ‫‪45‬‬ ‫‪300‬‬ ‫‪-90‬‬ ‫‪500‬‬ ‫‪30‬‬ ‫‪NULL‬‬
‫‪0‬‬

‫‪Temp‬‬ ‫‪Temp2‬‬

‫ث‪ -‬اسناد عنوان العقدة التالية للعقدة ال ُمراد حذفها لحقل العنوان الخاص بالعقدة السابقة للعقدة المراد حذفها‬
‫;‪Temp->link=Temp2->link‬‬
‫‪130‬‬ ‫‪200‬‬ ‫‪300‬‬ ‫‪500‬‬
‫‪130‬‬ ‫‪0100‬‬ ‫‪200‬‬ ‫‪45‬‬ ‫‪500‬‬ ‫‪-90‬‬ ‫‪500‬‬ ‫‪30‬‬ ‫‪NULL‬‬
‫‪0‬‬

‫‪Temp‬‬ ‫‪Temp2‬‬

‫ج‪ -‬حذف العقدة فعليا ً من الذاكرة فيصبح شكل القائمة بعد الحذف كما يلي‪:‬‬
‫;‪delete Temp2‬‬

‫‪130‬‬ ‫‪200‬‬ ‫‪500‬‬


‫‪130‬‬ ‫‪0100‬‬ ‫‪200‬‬ ‫‪45‬‬ ‫‪500‬‬ ‫‪30‬‬ ‫‪NULL‬‬
‫‪0‬‬
‫{ )‪int Deleting_position (int pos‬‬
‫{ )‪if (head==NULL‬‬
‫;"‪cout<<"empty List‬‬
‫};‪return 0‬‬
‫)‪else if (pos==1‬‬
‫;) ( ‪Deleting_begining‬‬
‫{‪else‬‬
‫;‪Node *Temp=head‬‬

‫‪39‬‬
‫ ماجد البعداني‬/.‫م‬ lab.6: Linked Lists (II) -‫عملي‬-‫هياكل بيانات وخوارزميات‬
Node *Temp2;
for (int i=1;i<pos-1;i++){
Temp= Temp -> link;
}
Temp2=Temp->link;
int x=Temp2->data;
Temp -> link =Temp2->link;
return x;
}}
‫✓ سوف نختبر دوال الحذف المكتوبة باألعلى بعد ان نقوم ببناء قائمة مترابطة ولبناء القائمة نحتاج أحد دوال اإلضافة مع حلقة‬
:)‫تكرارية (هنا سوف استخدم دالة اإلضافة في البداية مع حلقة تكراريه لبناء القائمة‬
#include<iostream>
#include<conio.h>
using namespace std;
struct Node{
int data;
Node *link ;
};
Node *head;
void inserting_beginning (int x){
struct Node *Temp= new Node( );
Temp->data= x;

Temp->link=head;
head=Temp;
}
int Deleting_begining ( ) {
if (head==NULL)
cout<<"Empty List";
else
{
Node *Temp=head;
int x=Temp -> data;
head = Temp->link;
return x;
}}

40
‫ ماجد البعداني‬/.‫م‬ lab.6: Linked Lists (II) -‫عملي‬-‫هياكل بيانات وخوارزميات‬

int Deleting_position (int pos) {


if (head==NULL) {
cout<<"empty List";
return 0;}
else if (pos==1)
Deleting_begining ( );
else{
Node *Temp=head;
Node *Temp2;
for (int i=1;i<pos-1;i++){
Temp= Temp -> link;
}
Temp2=Temp->link;
int x=Temp2->data;
Temp -> link =Temp2->link;
return x;
}}
void print () {
struct Node *Temp=head;
cout<<" The list is: " ;
while (Temp!=NULL) {
cout<<Temp->data<<" " ;
Temp= Temp->link;
}
cout<<endl ;
}
main( ){
head=NULL ;
int n,x,pos;
cout<<"enter the number of elements n= ";
cin>>n;
cout<<" enter the elements "<<'\n';

for (int i=1;i<=n; i++){


cout<<"enter element: ";

41
‫م‪ /.‬ماجد البعداني‬ ‫)‪lab.6: Linked Lists (II‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫;‪cin>>x‬‬
‫} ;)‪inserting_beginning (x‬‬
‫;‪cout<<"the list before deleting any item is: "<<endl‬‬
‫;) (‪print‬‬
‫;‪cout<<"__________________________________________________"<<endl‬‬
‫;‪cout<<"the list after deleting at beginning"<<endl‬‬
‫;) ( ‪int y=Deleting_begining‬‬
‫;‪cout<<" deleted element= "<<y<<endl‬‬
‫;)( ‪print‬‬
‫;‪cout<<"the list after deleting the third Node"<<endl‬‬
‫;)‪y= Deleting_position (3‬‬
‫;‪cout<<" deleted element= "<<y<< endl‬‬
‫;)( ‪print‬‬
‫;)(‪getch‬‬
‫}‬

‫تمارين إضافية عىل القوائم ر‬


‫المتابطة‬
‫❖ تمرين ‪ :1‬قم ببناء قائمة مترابطة مكونه من العناصر التالية بالترتيب المذكور ادناه (في حالة استخدام دالة اإلضافة في البداية‬
‫لبناء القائمة سوف نقوم بإدخال العناصر من اليمين لليسار وفي حالة استخدام دالة اإلضافة في النهاية سوف نقوم بإدخال العناصر‬
‫من اليسار لليمين)‬
‫‪50 20 70 40 20 10 20 23 15 -90 30 50‬‬
‫ثم قم بكتابة‪:‬‬
‫‪ -1‬دالة للبحث عن عنصر معين يقوم بإدخاله المستخدم في القائمة المترابطة (تُرجع ارقام العقد الموجود فيها العنصر)‪.‬‬
‫‪ -2‬دالة لحذف جميع العقد الموجودة في القائمة المترابطة‪.‬‬

‫‪42‬‬
‫ ماجد البعداني‬/.‫م‬ lab.6: Linked Lists (II) -‫عملي‬-‫هياكل بيانات وخوارزميات‬

‫إجابة السؤال السابق‬


#include<iostream>
#include<conio.h>
using namespace std;
struct Node{
int data;
Node *link ;
};
Node *head;

void inserting_beginning (int x){


struct Node *Temp= new Node( );
Temp->data= x;
Temp->link=head;
head=Temp;
}
void print () {
struct Node *Temp=head;
cout<<" The list is: " ;
while (Temp!=NULL) {
cout<<Temp->data<<" " ;
Temp= Temp->link;
}
cout<<endl ;
}
void search(int element)
{
Node *Temp=head;
int Node_num=1; //‫لحساب رقم العقدة الموجود فيها العنصر‬
int count=0; // ‫لفحص اذا كان العنصر غير موجود‬
cout<<"the element "<<element<<" is in nodes :";
while(Temp!=NULL)
{
if(Temp->data==element)
{

43
‫ ماجد البعداني‬/.‫م‬ lab.6: Linked Lists (II) -‫عملي‬-‫هياكل بيانات وخوارزميات‬

cout<<Node_num<<" ";
count++;
}
Temp=Temp->link;
Node_num++;
}
if (count==0)
cout<<"the element is not found";
cout<<endl;
}
void initialize()
{
Node *Temp=head;
while(head!=NULL)
{
Temp=head;
head=head->link;
delete Temp;
}
}
main( ){
head=NULL ;
int n,x;
cout<<"enter the number of elements n= ";
cin>>n;
cout<<" enter the elements "<<endl;
for (int i=1;i<=n; i++){
cout<<"enter element: ";
cin>>x;
inserting_beginning (x);
}
print();
cout<<"enter the element to search about:";
cin>>x;
search(x);

44
‫م‪ /.‬ماجد البعداني‬ ‫)‪lab.6: Linked Lists (II‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬
‫;‪cout<<"the list after deleting all nodes is: "<<endl‬‬
‫;)(‪initialize‬‬
‫}‬

‫❖ تمرين ‪ :2‬قم ببناء قائمتين مترابطتين وادخل اليهما العناصر التالية (سوف استخدم داله اإلضافة في النهاية)‬
‫األولى‪80 -20 100 50 60 70 :‬‬
‫الثانية‪500 600 700 800 900 :‬‬
‫ثم قم بكتابة دالة لدمج القائمتين المترابطتين (القائمة األولى ثم الثانية)‪.‬‬
‫• مالحظات هامة قبل قراءة البرنامج‪:‬‬
‫‪ -1‬كل قائمة مترابطة كما عرفنا سابقا ً بتكون معرفه برأسها (المتغير الذي يحتوي على عنوان اول عقدة في القائمة)‪ ،‬وبما اننا نحتاج‬
‫قائمتين فسوف نُعرف رأس للقائمة األولى (هنا اسميناه ‪ )first‬ورأس للقائمة الثانية (هنا اسميناه ‪.)second‬‬
‫‪ -2‬في البرامج السابقة كنا نعرف رأس القائمة كمتغير عام (‪ )global variable‬وبالتالي نستطيع الدخول الية من أي مكان في البرنامج‪،‬‬
‫لكن هنا قمنا بتعريف رأسي القائمتين كمتغيرين محليين (‪ )local variable‬في دالة ‪ main‬وبالتالي سوف نكون بحاجة إلرسال قيمها‬
‫للدوال واستقبالها ومن ثم ارجاعها اما عن طريق ‪ return‬او عن طريق استخدام المؤشرات‪.‬‬
‫>‪#include<iostream‬‬
‫>‪#include<conio.h‬‬
‫;‪using namespace std‬‬
‫{‪struct Node‬‬
‫;‪int data‬‬
‫; ‪Node *link‬‬
‫;}‬
‫)‪void print ( Node *head‬‬

‫‪45‬‬
‫ ماجد البعداني‬/.‫م‬ lab.6: Linked Lists (II) -‫عملي‬-‫هياكل بيانات وخوارزميات‬

{
Node *Temp=head;
cout<<" The list is: " ;

while (Temp!=NULL) {
cout<<Temp->data<<" " ;
Temp= Temp->link;
}
cout<<endl ;
}
Node * Inserting_End(Node *head,int x) {
Node *Temp= new Node ();
Temp->data= x;
Temp->link= NULL;
if(head==NULL)
head=Temp;
else
{
Node *Temp2=head ;
while (Temp2 -> link != NULL){
Temp2= Temp2->link; }
Temp2->link=Temp;
}
return head;
}
// ‫) وتعمل على دمج القائمة الثانية للقائمة األولى‬first, second( ‫هذه الدالة تستقبل رأسي القائمتين‬
void merge(Node **first,Node **second)
{
//‫إذا كانت القائمة األولى فارغة‬
if (*first==NULL)
*first=*second;
else
{

46
‫ ماجد البعداني‬/.‫م‬ lab.6: Linked Lists (II) -‫عملي‬-‫هياكل بيانات وخوارزميات‬

Node *Temp=*first;
while (Temp->link!=NULL)
Temp=Temp->link;

Temp->link=*second;
}
}
main (){
Node *first=NULL;
Node *second=NULL;
int x,n;
cout<<"enter the number of elements for the first linked list: ";
cin>>n;
cout<<" enter the elements "<<endl;
for (int i=1;i<=n; i++){
cout<<"enter element: ";
cin>>x;
first=Inserting_End (first,x);
}
cout<<"enter the number of elements for the second linked list: ";
cin>>n;
cout<<" enter the elements "<<endl;
for (int i=1;i<=n; i++){
cout<<"enter element: ";
cin>>x;
second=Inserting_End (second,x);
}
cout<<"___________________________________________"<<endl;
cout<<" the two lists befor merging are : "<<endl;
print(first);
print(second);
cout<<"___________________________________________"<<endl;
cout<<" the tow lists after merging is: "<<endl;

47
‫ ماجد البعداني‬/.‫م‬ lab.6: Linked Lists (II) -‫عملي‬-‫هياكل بيانات وخوارزميات‬

merge(&first,&second);
print(first);
}

48
‫م‪ /.‬ماجد البعداني‬ ‫‪lab.7: Doubly Linked Lists & stack and Queue using Linked List‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫❖ القائمة المترابطة الثنائية هي عبارة عن قائمة مترابطة كل عقدة فيها تحتوي على ثالثة حقول‪ ،‬حقل للبيانات وحقل يحتوي عنوان‬
‫العقدة التالية وحقل يحتوي عنوان العقدة السابقة كما هو مبين بالشكل التالي‪ ،‬ال ‪ first‬هنا يحتوي عنوان اول عقدة وال ‪last‬‬
‫ُمشير آلخر عقدة‪.‬‬

‫❖ العمليات األساسية ال ُممكن تنفيذها على القائمة المترابطة الثنائية هي‪:‬‬


‫إضافة عقدة جديدة الى القائمة‪:‬‬ ‫‪-‬‬
‫‪ -1‬في البداية‪.‬‬
‫‪ -2‬في النهاية‪.‬‬
‫‪ -3‬في موقع معين‪.‬‬
‫حذف عقدة من القائمة‪:‬‬ ‫‪-‬‬
‫‪ -1‬من البداية‪.‬‬
‫‪ -2‬من النهاية‪.‬‬
‫‪ -3‬من موقع معين‪.‬‬
‫عملية ال ‪( traversing‬زيارة جميع العُقد في القائمة)‪.‬‬ ‫‪-‬‬
‫❖ البرنامج التالي يضُم جميع العمليات المذكورة في األعلى‪:‬‬
‫>‪#include<iostream‬‬
‫>‪#include<conio.h‬‬
‫;‪using namespace std‬‬
‫‪/* structure representing a node of the doubly linked list */‬‬
‫{‪struct dnode‬‬
‫;‪dnode *prev‬‬
‫;‪int data‬‬
‫;‪dnode *next‬‬
‫;}‬
‫‪/* adds a new node at the begining of the linked list */‬‬
‫)‪void insert_begin(dnode* &f,dnode* &l,int x‬‬
‫{‬
‫‪dnode *temp=new dnode; // creation of a new node‬‬
‫;‪temp->data=x‬‬
‫;‪temp->prev=NULL‬‬

‫‪49‬‬
‫ ماجد البعداني‬/.‫م‬ lab.7: Doubly Linked Lists & stack and Queue using Linked List -‫عملي‬-‫هياكل بيانات وخوارزميات‬

if (f==NULL) //empty list


{
f=temp;
l=temp;
temp->next=NULL;
}
else
{
temp->next=f;
f->prev=temp;
f=temp;
}
}
/* adds a new node at the end of the doubly linked list */
void insert_end(dnode* &f,dnode* &l,int x)
{
dnode *temp=new dnode; // creation of a new node
temp->data=x;
temp->next=NULL;
if (f==NULL) //empty list
{
f=temp;
l=temp;
temp->prev=NULL;
}
else
{
l->next=temp;
temp->prev=l;
l=temp;
}
}
/* adds a new node at a specified location*/
void insert_Location(dnode* &f,dnode* &l,int x,int loc)
{

50
‫ ماجد البعداني‬/.‫م‬ lab.7: Doubly Linked Lists & stack and Queue using Linked List -‫عملي‬-‫هياكل بيانات وخوارزميات‬

dnode *temp=new dnode; // creation of a new node


if (f==NULL)
{
f=temp;
l=temp;
temp->data=x;
temp->prev=NULL;
sstemp->next=NULL;
}
else
{
dnode *t=f;
for (int i=1;i<loc-1;i++)
t=t->next;
temp-> next=t->next;
temp->prev=t->next->prev;
t->next->prev=temp;
t->next=temp;
}
}
/* displays the contents of the linked list */
void print(dnode *f)
{
dnode *t=f;
while(t!=NULL)
{
cout<<t->data<<" ";
t=t->next;
}
cout<<endl;
}
/* deletes the specified node from the doubly linked list */
void Delete_n(dnode* &f,dnode *&l,int x)
{
dnode *t=f;

51
‫ ماجد البعداني‬/.‫م‬ lab.7: Doubly Linked Lists & stack and Queue using Linked List -‫عملي‬-‫هياكل بيانات وخوارزميات‬

while(t!=NULL)
{
/* if node to be deleted is found */
if (t->data==x)
{
/* if node to be deleted is the first node */
if (t==f)
{
f=f->next;
f->prev=NULL;
}

else
{
/* if node to be deleted is the last node */
if (t->next==NULL)
{
t->prev->next=NULL;
l=t->prev;
}
else
{
/* if node to be deleted is any intermediate node */
t->prev->next=t->next;
t->next->prev=t->prev;
}
}
delete t;
return ; /* return back after deletion */
}
t=t->next;
}
}
void main()
{

52
‫ ماجد البعداني‬/.‫م‬ lab.7: Doubly Linked Lists & stack and Queue using Linked List -‫عملي‬-‫هياكل بيانات وخوارزميات‬

dnode *first=NULL; // pointer to the first node


dnode *last=NULL; // pointer to the last node
insert_begin(first,last,50);
insert_begin(first,last,10);
insert_end(first,last,150);
insert_end(first,last,200);
print(first);
insert_Location(first,last,60,2);
insert_Location(first,last,70,3);
print(first);
cout<<endl<<"the list after deleting element 150 and 10 is"<<endl;
Delete_n(first,last,150);
Delete_n(first,last,10);
print(first);
getch();
}

‫ جبميع عملياته باستخدام القوائم املرتابطة بدال من استخدام املصفوفات‬stack ‫تصميم ال‬

.‫ للقائمة المترابطة‬Head ‫ هو نفسه ال‬TOS ‫ ال‬-


.‫) هي نفسها عملية اضافه عقدة جديدة في البداية‬push( ‫ عملية إضافة عنصر جديد للمكدس‬-
.‫) هي نفسها عملية حذف عقدة من البداية‬pop( ‫ عملية حذف عنصر من المكدس‬-
TOS==NULL ‫ يكون المكدس فارغا ً إذا كان‬-
.ً‫ ال يمكن ان يكون المكدس ممتلئا‬-
:Push ‫ عملية‬:‫• اولا‬
:‫ كانت بالشكل التالي‬stack ‫لنفرض ان ال‬
.TOS ‫ الموجود في االشكال هو نفسه‬stackTop :‫• مالحظة‬

53
‫م‪ /.‬ماجد البعداني‬ ‫‪lab.7: Doubly Linked Lists & stack and Queue using Linked List‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫الشكل التالي يوضح خطوات عملية اإلضافة (بفرض ان القيمة ال ُمراد اضافتها هي '‪)'D‬‬

‫• ثانياا‪ :‬عملية ‪Pop‬‬


‫لنفرض ان ال ‪ stack‬كانت بالشكل التالي‪:‬‬

‫الشكل التالي يوضح خطوات عملية حذف عنصر من المكدس (التي يُشير اليها ال ‪)stackTop‬‬

‫‪54‬‬
‫ ماجد البعداني‬/.‫م‬ lab.7: Doubly Linked Lists & stack and Queue using Linked List -‫عملي‬-‫هياكل بيانات وخوارزميات‬

:‫• البرنامج التالي لتصميم المكدس بجميع عملياته باستخدام القوائم المترابطة‬

#include<iostream>
using namespace std;
struct node
{
int data;
node *link;
};
struct stackType
{
node *Tos;
};
void initializeStack (stackType &curr)
{
node *t;
while(curr.Tos!=NULL)
{
t=curr.Tos;
curr.Tos=curr.Tos->link;
delete t;
}
}
bool isEmpty(stackType current)
{
return (current.Tos==NULL);
}
bool isFull(stackType current)
{
return false;
}
void push(stackType &current,int element)
{
node *t=new node;
t->data=element;

55
‫ ماجد البعداني‬/.‫م‬ lab.7: Doubly Linked Lists & stack and Queue using Linked List -‫عملي‬-‫هياكل بيانات وخوارزميات‬

t->link=current.Tos;
current.Tos=t;
}
int pop(stackType &current)
{
if(!isEmpty(current))
{
node *t=current.Tos;
current.Tos=current.Tos->link;
int x=t->data;
delete t;
return x;
}
else
{
cout<<"the stack is empty";
return 0;
}
}
void print(stackType curr)
{
while(!isEmpty(curr))
{
cout<<curr.Tos->data<<" ";
curr.Tos=curr.Tos->link;
}
cout<<"\n";
}
main()
{
stackType stack;
stack.Tos=NULL;
push(stack,48);print(stack);
push(stack,15);print(stack);
push(stack,500);print(stack);

56
‫ ماجد البعداني‬/.‫م‬ lab.7: Doubly Linked Lists & stack and Queue using Linked List -‫عملي‬-‫هياكل بيانات وخوارزميات‬

push(stack,-20);print(stack);
int x;
x=pop(stack);
cout<<"the poped element is: "<<x<<endl;
print(stack);
x=pop(stack);
cout<<"the poped element is: "<<x<<endl;
print(stack);
x=pop(stack);
cout<<"the poped element is: "<<x<<endl;
print(stack);
x=pop(stack);
}

‫ جبميع عملياته باستخدام القوائم املرتابطة بدال من استخدام املصفوفات‬Queue ‫تصميم ال‬

:)‫• البرنامج التالي لتصميم المكدس بجميع عملياته باستخدام القوائم المترابطة (قم بتحليله بنفسك‬

#include<iostream>
using namespace std;
struct node
{
int data;
node *link;
};
struct queueType{

node *Front;
node *Rear;
};
void initializeQueue(queueType &curr,int max)
{
node *t;
while(curr.front!=NULL)
{
t=curr.front;

57
‫ ماجد البعداني‬/.‫م‬ lab.7: Doubly Linked Lists & stack and Queue using Linked List -‫عملي‬-‫هياكل بيانات وخوارزميات‬

curr.front=curr.front->link;
delete t;
}
curr.rear=NULL;
}
bool isEmpty(queueType &curr)
{
return (curr.front==NULL);
}
bool isFull(queueType &curr)
{
return false;
}
void addQueue(queueType &curr,int x)
{
node *temp=new node;
temp->data=x;
temp->link=NULL;
if (curr.rear==NULL) //if initially the queue is empty
{
curr.front=temp;
curr.rear=temp;
}
else
{ //add newNode at the end
curr.rear->link=temp;
curr.rear=curr.rear->link;
}
}
int deleteQueue(queueType &curr)
{
if(!isEmpty(curr))
{
node *temp=curr.front;
curr.front=curr.front->link;

58
‫ ماجد البعداني‬/.‫م‬ lab.7: Doubly Linked Lists & stack and Queue using Linked List -‫عملي‬-‫هياكل بيانات وخوارزميات‬

int x=temp->data;
delete temp;
if(curr.front==NULL) //if after deletion the queue is empty
curr.rear = NULL; //set rear to NULL
return x;
}
else
{
cout<<"empty Queue";
return 0;
}
}
void print(queueType curr)
{
cout<<"queue elements: ";
while(!isEmpty(curr))
{
cout<<curr.front->data<<" ";
curr.front=curr.front->link;
}
}
cout<<endl;
}
void main( ){
queueType queue;
queue.front=NULL;
queue.rear=NULL;
int x,n;
cout<<"enter the number of element to add into queue: ";
cin>>n;
for(int i=0;i<n;i++){
cin>>x;
addQueue(queue,x);}
print(queue);
cout<<"the deleted element: "<<deleteQueue(queue)<<endl;

59
‫ ماجد البعداني‬/.‫م‬ lab.7: Doubly Linked Lists & stack and Queue using Linked List -‫عملي‬-‫هياكل بيانات وخوارزميات‬

print(queue);
cout<<"the deleted element: "<<deleteQueue(queue)<<endl;
print(queue);}

60
‫م‪ /.‬ماجد البعداني‬ ‫)‪lab.8: Trees (I‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫❖ مفهوم الشجرة‪:‬‬
‫هي مجموعة منتهية مكونه من عقدة او أكثر بحيث تحقق ما يلي‪:‬‬
‫‪ .1‬يوجد عقدة مصممة بشكل خاص تدعى جذر الشجرة(‪)root‬‬
‫‪ .2‬العقد المتبقية تُجزأ الى (‪ )n≥0‬من المجموعات المنفصلة ‪ T1, T2, T3,….. , Tn‬حيث كل مجموعة من هذه المجموعات‬
‫تشكل شجرة‪ .‬تُدعى هذه المجموعات اشجارا ً فرعية (‪ )sub-trees‬من عقدة الجذر كما هو موضح بالشكل التالي‪:‬‬

‫❖ تعاريف هامة‪:‬‬

‫بفرض ان لدينا شجرة ‪T‬‬


‫‪ -1‬درجة عقدة (‪ )degree of node‬هي عدد األشجار الفرعية لهذه العقدة‪ .‬فمثلً درجة العقدة ‪ A‬تساوي ‪ 3‬ودرجة العقدة ‪C‬‬
‫تساوي ‪ 1‬ودرجة العقدة ‪ F‬صفر‪.‬‬
‫درجة الشجرة ()‪ )degree(T‬هو العدد األعظمي لألشجار الفرعية لعقدة ما أي ان‪:‬‬
‫}‪ .degree (T) = max{degree(x) | x is a node of T‬درجة الشجرة ‪ T‬تساوي ‪3‬‬
‫‪ -2‬تُسمى كل عقدة لها شجرة فرعية واحدة على األقل عقدة داخلية (‪ )internal node‬مثل العقد ‪A,B,C,D,E,H‬‬
‫تُسمى كل عقدة ليس لها شجرة فرعية عقدة ورقية (‪ )leaf node‬او عقدة خارجية (‪ )external node‬مثل العقد‬
‫‪K,L,F,G,M,I,J‬‬
‫‪ -3‬يمكن ان توجد بين العقد العلقات التالية‪ :‬أب (‪ – )parent‬ابن (‪ – )children‬أخ (‪ – )sibling‬سلف (‪.)ancestor‬‬
‫نقول عن عقدتين انهما أختان (‪ )siblings‬إذا كان لهما االب نفسه‪ .‬مثلً العقدة ‪ B‬أب للعقد ‪ ،F,E‬وبالعكس العقدتان ‪F,E‬‬
‫أوالد للعقدة ‪ ،B‬كما ان العقد ‪ H,I,J‬أخوات‪.‬‬
‫نقول عن العقدة ‪ x‬انها سلف لعقدة ‪ ،Y‬إذا وفقط إذا كانت ‪ x‬أبا ً ل ‪ ،y‬أو كانت ‪ x‬سلفا ً ألب‪ .‬مثل‪ :‬كلً من العقد ‪H,D,A‬‬
‫يكون سلفا ً للعقدة ‪.M‬‬
‫‪ -4‬ارتفاع عقدة ‪ )height(x)( X‬هو عدد االتصاالت (‪ )edges‬في المسار الواصل بين هذه العقدة وعقدة الجذر‪ .‬مثلُ‬
‫‪. height(E)=3،height(M)=3‬‬
‫ارتفاع شجرة ‪ T‬هو أطول ارتفاع عقدة في الشجرة‪.‬‬

‫‪61‬‬
‫م‪ /.‬ماجد البعداني‬ ‫)‪lab.8: Trees (I‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫}‪ .height (T) =max {height (x): x is a node in T‬مثل ارتفاع الشجرة الموجودة في األعلى يساوي ‪3‬‬
‫‪ -5‬عمق عقدة ‪ )depth(x)( x‬هو عدد االتصاالت (‪ )edges‬في أطول مسار من هذه العقدة الى عقدة ورقية (‪.)leaf node‬‬
‫مثلً ‪Depth(B)=2, Depth(C)=1‬‬

‫األشجار الثنائية (‪)Binary Trees‬‬


‫❖ تعريفها‪:‬‬
‫هي عبارة عن مجموعة منتهية من العقد بشرط ان كل عقدة يكون لها ابنان على األكثر‪ .‬واالشكال التالية كلها تمثل أشجار ثنائية‪:‬‬

‫‪1‬‬

‫‪2‬‬ ‫‪3‬‬ ‫‪4‬‬ ‫‪5‬‬


‫‪2‬‬
‫❖ تمثيل الشجرة الثنائية برمجيا‪:‬‬
‫أ‪ -‬كل عقدة في الشجرة الثنائية تتكون من ثلثة حقول‪:‬‬
‫‪ -1‬حقل لخزن البيانات ‪info‬‬
‫‪ -2‬حقل لخزن عنوان العقدة اليمينية (‪)Llink‬‬
‫‪ -3‬حقل لخزن عنوان العقدة اليسارية (‪)Rlink‬‬
‫ب‪ -‬مؤشر للعقدة الجذر (لخزن عنوان العقدة الجذر) يُسمى ‪root‬‬
‫وبالتالي تُمثل العقدة كما يلي‪:‬‬
‫‪struct binaryTreeNode‬‬
‫{‬
‫;‪elemType info‬‬
‫;‪binaryTreeNode *llink‬‬
‫;‪binaryTreeNode *rlink‬‬
‫}‬
‫;‪binaryTreeNode *root‬‬

‫‪62‬‬
‫م‪ /.‬ماجد البعداني‬ ‫)‪lab.8: Trees (I‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫وبالتالي يُصبح شكل الشجرة الثنائية في الشكل ‪ 1‬الموجود في الصفحة السابقة كالتالي‪:‬‬

‫‪( Binary Tree Traversal‬التنقل عبر األشجار الثنائية)‬


‫يقصد بعملية التنقل المرور بكل عقدة (زيارة كل عقدة) من عقد الشجرة مرة واحدة حسب ترتيب معين بهدف اجراء معالجة معينة‬
‫عليها (طباعة حقل البيانات في العقدة مثالً)‪ .‬التنقل على كامل الشجرة سينتج ترتيبا ُ خطيا َ للبيانات في الشجرة‪.‬‬
‫هناك ثالثة أساليب للتنقل عبر عقد شجرة ثنائية وهي كالتالي‪:‬‬
‫‪ Inorder Traversal -1‬وتمر بثالث خطوات‪:‬‬
‫التنقل عبر الشجرة الفرعية اليسارية للعقدة‬ ‫‪-‬‬
‫زيارة العقدة‬ ‫‪-‬‬
‫التنقل عبر الشجرة الفرعية اليمينية للعقدة‬ ‫‪-‬‬
‫‪ Preorder Traversal -2‬وتمر بثالث خطوات‪:‬‬
‫زيارة العقدة‬ ‫‪-‬‬
‫التنقل عبر الشجرة الفرعية اليسارية للعقدة‬ ‫‪-‬‬
‫التنقل عبر الشجرة الفرعية اليمينية للعقدة‬ ‫‪-‬‬
‫‪ Postoreder Traversal -3‬وتمر بثالث خطوات‪:‬‬
‫التنقل عبر الشجرة الفرعية اليسارية للعقدة‬ ‫‪-‬‬
‫التنقل عبر الشجرة الفرعية اليمينية للعقدة‬ ‫‪-‬‬
‫زيارة العقدة‬ ‫‪-‬‬
‫لكتابة اكواد هذه الدوال سوف نستخدم االستدعاء الذاتي (‪:)Recursion‬‬
‫)‪void inorder(binaryTreeNode *p‬‬
‫{‬
‫)‪if (p != NULL‬‬
‫{‬
‫;)‪inorder(p->llink‬‬
‫;" " << ‪cout << p->info‬‬
‫;)‪inorder(p->rlink‬‬
‫}}‬

‫‪63‬‬
‫م‪ /.‬ماجد البعداني‬ ‫)‪lab.8: Trees (I‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫)‪void preorder(binaryTreeNode *p‬‬


‫{‬
‫)‪if (p != NULL‬‬
‫{‬
‫;" " << ‪cout << p->info‬‬
‫;)‪preorder(p->llink‬‬
‫;)‪preorder(p->rlink‬‬
‫}‬
‫}‬
‫‪void postorder(binaryTreeNode‬‬ ‫)‪*p‬‬
‫{‬
‫)‪if (p != NULL‬‬
‫{‬
‫;)‪postorder(p->llink‬‬
‫;)‪postorder(p->rlink‬‬
‫;" " << ‪cout << p->info‬‬
‫}‬
‫}‬
‫❖ لنفرض ان لدينا الشجرة الثنائية الموجودة في الشكل التالي‪:‬‬

‫في حالة استخدمنا طريق ‪ Inorder‬سوف تُطبع العناصر بالترتيب التالي‪:‬‬ ‫•‬
‫‪D G B E A C H F‬‬

‫في حالة استخدمنا طريق ‪ Preorder‬سوف تُطبع العناصر بالترتيب التالي‪:‬‬ ‫•‬
‫‪A B D G E C F H‬‬

‫في حالة استخدمنا طريق ‪ Postorder‬سوف تُطبع العناصر بالترتيب التالي‪:‬‬ ‫•‬
‫‪G D E B H F C A‬‬

‫شجرة البحث الثنائية (‪) Binary Search Tree‬‬

‫‪64‬‬
‫م‪ /.‬ماجد البعداني‬ ‫)‪lab.8: Trees (I‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫عبارة عن شجرة ثنائية لكن بشرط ان قيم كل العقد الموجودة على يمين عقدة ما أكبر من قيمة العقدة نفسها وقيم كل العقد الموجودة‬
‫على يسارها اقل من قيمة العقدة نفسها‪ .‬هذا الترتيب سوف يجعل عملية البحث أكثر سرعة وكفاءة‪.‬‬

‫وللتوضيح أكثر الحظ األمثلة التالية‪:‬‬

‫الشكل ‪ :2‬شجرة ثنائيه لكنها ليست شجرة بحث ثنائية‬ ‫الشكل ‪ :1‬شجرة ثنائيه لكنها ليست شجرة بحث ثنائية‬
‫❖ العمليات األساسية الممكن تطبيقها على شجرة البحث الثنائية‪:‬‬
‫‪ -1‬اضافه عنصر جديدة الى الشجرة‬
‫‪ -2‬حذف عنصر من الشجرة‬
‫‪ -3‬التنقل عبر شجرة البحث الثنائية‪.‬‬
‫‪ -4‬البحث عن عنصر معين في للشجرة‬
‫‪ -5‬حساب أكبر واقل قيمة في الشجرة‬
‫‪ -6‬حساب طول (‪ )height‬شجرة البحث الثنائية‪.‬‬

‫العملية األولى‪ :‬اضافه عنصر جديد الى شجرة البحث الثنائية‪:‬‬


‫لو افترضنا ان لدينا الشجرة الموجودة في الشكل ‪ 1‬في األعلى ونريد اضافه عنصرين ولتكن ‪ 9‬و‪ 19‬على التوالي سوف تصبح‬
‫الشجرة كالتالي‪:‬‬

‫‪9‬‬ ‫‪19‬‬

‫✓ الكود البرمجي لعملية اإلضافة هو كالتالي‪:‬‬

‫‪65‬‬
‫ ماجد البعداني‬/.‫م‬ lab.8: Trees (I) -‫عملي‬-‫هياكل بيانات وخوارزميات‬

binaryTreeNode * getnewnode(int element)


{
binaryTreeNode *temp=new node;
temp->data=element;
temp->left=temp->right=NULL;
return temp;
}
void insertBST(int element)
{
binaryTreeNode *current;
binaryTreeNode *tempcurrent;
binaryTreeNode *newnode=getnewnode(element);
if (root==NULL)
root=newnode;
else
{
current=root;
while(current!=NULL)
{
tempcurrent=current;
if (current->data==element)
{
cout<<"duplicated value is not allowed";
return;
}
else if(current->data>element)
current=current->left;
else
current=current->right;
}
if (tempcurrent->data>element)
tempcurrent->left=newnode;
else
tempcurrent->right=newnode;
}
}

66
‫م‪ /.‬ماجد البعداني‬ ‫‪lab.8: Trees (II): Follow Binary Search Tree‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫❖ البحث في شجرة البحث الثنائية ‪:Searching a Binary Search Tree‬‬

‫لنفرض أننا نرغب بالبحث عن عنصر ب ‪ key‬يساوي ‪ x‬في شجرة بحث ثنائية‪ .‬نبدأ أوال بالجذر‪ .‬إذا كان الجذر يساوي ‪،NULL‬‬
‫أي شجرة البحث ال تضمن أي عنصر‪ ،‬وبالتالي البحث ينتهي بفشل‪ .‬وإال‪ ،‬نقارن ‪ X‬مع ‪ key‬الجذر‪ ،‬فإذا كانا متساويين‪ ،‬عندئذ البحث‬
‫ينتهي بنجاح‪ .‬أما إذا كان ‪ x‬أصغر من ‪ key‬الجذر فعندئذ يتم البحث في الشجرة الفرعية اليسارية للجذر‪ ،‬ألنه ال يوجد عنصر في‬
‫الشجرة الفرعية اليمينية له ‪ key‬يساوي‪ .‬وإذا كان ‪ x‬أكبر من ‪ key‬الجذر عندئذ يتم البحث في الشجرة الفرعية اليمينية للجذر‪.‬‬

‫‪ -‬الدالة اإلجرائية التكرارية المسؤولة عن تنفيذ عملية البحث هي‪:‬‬


‫)‪binaryTreeNode *iter_search(binaryTreeNode *root, int x‬‬
‫{‬
‫‪/* return a pointer to the node that contains x. If there is no such node, return null */‬‬
‫{ )‪while (root !=NULL‬‬
‫;‪if (x == root->data) return root‬‬
‫)‪if (x < root ->data‬‬
‫;‪root = root->left‬‬
‫‪else‬‬
‫;‪root = root->right‬‬
‫;‪return NULL‬‬
‫}‬
‫❖ البحث عن أصغر ‪ key‬وأكبر ‪ key‬في شجرة البحث الثنائية‪:‬‬
‫بفرض لدينا شجرة بحث ثنائية ‪ .tree‬ونرغب بالبحث عن عقدة تملك أصغر ‪ )minimum key( Key‬وعقدة تملك أكبر‬
‫‪.)maximum key) key‬‬

‫‪ -‬أوالً‪ :‬البحث عن أصغر ‪:key‬‬

‫يبدأ بالذهاب إلى االبن اليساري لعقدة الجذر‪ ،‬ومن ثم إلى ابنه اليساري‪ ،‬وهكذا حتى يتم الوصول إلى عقدة ال تتضمن ابنا‬
‫يسارية‪ .‬عندئذ تكون هذه العقدة تملك أصغر ‪ key‬في الشجرة‪ - .‬الدالة اإلجرائية المسؤولة عن ذلك‪:‬‬

‫) ‪int minimum (binaryTreeNode *roor‬‬


‫{‬
‫;‪binaryTreeNode *ptr‬‬
‫{)‪while(root !=NULL‬‬
‫;‪ptr = root‬‬
‫;‪root= root ->left‬‬
‫}‬
‫;‪return ptr->data‬‬
‫}‬
‫‪ -‬ثانيا‪ :‬البحث عن أكبر ‪:key‬‬

‫يأخذ هذا البحث المسار المعاكس حيث تتكرر العملية نفسها ولكن على االبن اليميني للعقدة‪ ،‬ويستمر حتى يتم العثور على عقدة ال‬
‫تتضمن ابنا يمينيا عندئذ تكون هذه العقدة تملك أكبر‪ key‬في الشجرة‪.‬‬

‫‪67‬‬
‫م‪ /.‬ماجد البعداني‬ ‫‪lab.8: Trees (II): Follow Binary Search Tree‬‬ ‫هياكل بيانات وخوارزميات‪-‬عملي‪-‬‬

‫‪ -‬الدالة اإلجرائية المسؤولة عن ذلك‪:‬‬


‫)‪int minimum (binaryTreeNode *root‬‬
‫{‬
‫;‪binaryTreeNode *ptr‬‬
‫{)‪while(root !=NULL‬‬
‫;‪ptr = root‬‬
‫;‪root= root ->right‬‬
‫}‬
‫;‪return ptr->data‬‬
‫}‬
‫❖ لنقم االن بكتابة البرنامج كام ً‬
‫ال بحيث يتضمن جميع الدوال التي اخذناها في هذه المحاضرة والدوال الموجودة في المحاضرة السابقة حيث‬
‫اننا سوف نقوم ببناء شجرة بحث ثنائية كما يلي‪:‬‬

‫مالحظة‪ :‬قم بإدخال العناصر ‪ level by level‬مثال عندما تقوم ببناء الشجرة السابقة تقوم بترتيب العناصر وادخالها كالتالي (من‬
‫اليسار لليمين)‪:‬‬

‫‪20 15 25 12 17 22 26 10 13 23 30‬‬
‫>‪#include<iostream‬‬
‫>‪#include<stdio.h‬‬
‫;‪using namespace std‬‬
‫‪struct binaryTreeNode‬‬
‫{‬
‫;‪int data‬‬
‫;‪binaryTreeNode *left‬‬
‫;‪binaryTreeNode *right‬‬
‫;}‬
‫)‪binaryTreeNode * getnewnode(int element‬‬

‫‪68‬‬
‫ ماجد البعداني‬/.‫م‬ lab.8: Trees (II): Follow Binary Search Tree -‫عملي‬-‫هياكل بيانات وخوارزميات‬
{
binaryTreeNode *temp=new binaryTreeNode;
temp->data=element;
temp->left=temp->right=NULL;
return temp;
}
binaryTreeNode * insertBST(binaryTreeNode *root,int element)
{
binaryTreeNode *current;
binaryTreeNode *tempcurrent;
binaryTreeNode *newnode=getnewnode(element);
if (root==NULL)
{
root=newnode;
}
else
{
current=root;
while(current!=NULL)
{
tempcurrent=current;
if (current->data==element)
{
cout<<"duplicated value is not allowed";
}
else if(current->data>element)
current=current->left;
else
current=current->right;
}
if (tempcurrent->data>element)
tempcurrent->left=newnode;

69
‫ ماجد البعداني‬/.‫م‬ lab.8: Trees (II): Follow Binary Search Tree -‫عملي‬-‫هياكل بيانات وخوارزميات‬
else
tempcurrent->right=newnode;
}
return root;
}
void inorder(binaryTreeNode *p)
{
if (p != NULL)
{
inorder(p->left);
cout << p->data << " ";
inorder(p->right);
}}
void preorder(binaryTreeNode *p)
{
if (p != NULL)
{
cout << p->data << " ";
preorder(p->left);
preorder(p->right);
}
}
void postorder(binaryTreeNode *p)
{
if (p != NULL)
{
postorder(p->left);
postorder(p->right);
cout << p->data << " ";
}
}
binaryTreeNode *search(binaryTreeNode *root, int x)

70
‫ ماجد البعداني‬/.‫م‬ lab.8: Trees (II): Follow Binary Search Tree -‫عملي‬-‫هياكل بيانات وخوارزميات‬
{
/* return a pointer to the node that contains x. If there is no such node, return null */
while (root !=NULL) {
if (x == root->data) return root;
if (x < root ->data)
root = root->left;
else
root = root->right;
}
return NULL;
}
int minimum(binaryTreeNode *root)
{
binaryTreeNode *ptr;
while(root !=NULL){
ptr = root;
root= root ->left;
}
return ptr->data;
}
int maximum (binaryTreeNode *root)
{
binaryTreeNode *ptr;
while(root !=NULL){
ptr = root;
root= root ->right;
}
return ptr->data;
}
main ()
{
binaryTreeNode *root=NULL; // empty BST

71
‫ ماجد البعداني‬/.‫م‬ lab.8: Trees (II): Follow Binary Search Tree -‫عملي‬-‫هياكل بيانات وخوارزميات‬
int x,n;
cout<<"enter the no. of nodes you need to add: ";
cin>>n;
cout<<"enter the elements:"<<endl;
for(int i=0;i<n;i++)
{
cin>>x;
root=insertBST(root,x);
}
cout<<"the preorder traversing: "<<endl;
preorder(root);
cout<<endl<<"the postorder traversing: "<<endl;
postorder(root);
cout<<endl<<"the inorder traversing: "<<endl;
inorder(root);
cout<<endl<<"the max element in the tree is : "<<maximum(root)<<endl;
cout<<"the min element in the tree is : "<<minimum(root)<<endl;
cout<<"enter the element to search:";
cin>>x;
binaryTreeNode * ptr;
ptr=search(root,x);
if (ptr==NULL)
cout<<"not found";
else
cout<<"the location of " <<ptr->data<<"is:"<<ptr;
}

72
Data Structures & Algorithms
Lab. 10:Graphs.

Directed Graph Undirected Graphs

 The two most common ways of representing graphs are:


1. Adjacency matrix
2. Adjacency List

Adjacency Matrix for Directed Graph Adjacency Matrix for Undirected Graph

Adjacency List for Directed Graph Adjacency List for Undirected Graph

73
 Suppose we have the following weighted directed graph:

6
0 1
7
5 4

2 10
3
4
6
3
4 5
1

 Adjacency matrix C++ implementation:


#include <iostream>
using namespace std;
const int N=6;
//initialize matrix to 0
void init(int arr[ ][N])
{
int i,j;
for(i = 0; i < N; i++)
for(j = 0; j < N; j++)
arr[i][j] = 0;
}
//Add edge. set arr[src][dest] = 1
void addEdge(int arr[][N],int src, int dest,int weight)
{
arr[src][dest] = weight;
}
void printAdjMatrix(int arr[][N])
{
int i, j;
cout<<"The adjacency matrix for the graph:"<<endl<<endl;
for(i = 0; i < N; i++)
{
for(j = 0; j < N; j++)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
}

74
//print the adjMatrix
int main()
{
int adjMatrix[N][N];

init(adjMatrix);
addEdge(adjMatrix,0,1,6);
addEdge(adjMatrix, 1,2,7);
addEdge(adjMatrix,2, 0, 5);
addEdge(adjMatrix,2, 1, 4);
addEdge(adjMatrix,3, 2, 10);
addEdge(adjMatrix,3,5,6);
addEdge(adjMatrix,4, 5, 1);
addEdge(adjMatrix,5, 4, 3);

printAdjMatrix(adjMatrix);
return 0;
}

 Adjacency List C++ implementation:


#include <iostream>
using namespace std;

// Define maximum number of vertices in the graph


const int N=6;

// A data structure to store adjacency list nodes of the graph


struct Node {
int dest, weight;
Node* next;
};

// Data structure to store graph

75
struct Graph {
// An array of pointers to Node to represent adjacency list
Node* head[N];
};
// data structure to store graph edges
struct Edge {
int src, dest, weight;

};

// Function to create an adjacency list from specified edges


Graph* createGraph(Edge edges[], int n)
{
int i;

// allocate memory for graph data structure


Graph* graph = new Graph;

// initialize head pointer for all vertices


for (i = 0; i < N; i++)
graph->head[i] = NULL;

// add edges to the directed graph one by one


for (i = 0; i < n; i++)
{
// get source and destination vertex
int src = edges[i].src;
int dest = edges[i].dest;
int weight = edges[i].weight;

// allocate new node of Adjacency List from src to dest


Node* newNode = new Node ;
newNode->dest = dest;
newNode->weight = weight;

// point new node to current head


newNode->next = graph->head[src];

// point head pointer to new node


graph->head[src] = newNode;
}

return graph;
}

76
// Function to print adjacency list representation of graph
void printGraph( Graph* graph)
{
int i;
for (i = 0; i < N; i++)
{
// print current vertex and all ts neighbors
Node* ptr = graph->head[i];
while (ptr != NULL)
{
cout<<i<<" -> "<<ptr->dest<<"("<<ptr->weight<<")"<<"\t";
ptr = ptr->next;
}

cout<<"\n";
}
}

// Weighted Directed Graph Implementation in C


int main(void)
{
// input array containing edges of the graph (as per above diagram)
// (x, y, w) tuple represents an edge from x to y having weight w
Edge edges[] =
{
{ 0, 1, 6 }, { 1, 2, 7 }, { 2, 0, 5 }, { 2, 1, 4 },
{ 3, 2, 10 }, { 4, 5, 1 }, { 5, 4, 3 },{5,3,6}
};
// calculate number of edges
int n = sizeof(edges)/sizeof(edges[0]);
// construct graph from given edges
Graph *graph = createGraph(edges, n);
// print adjacency list representation of graph
printGraph(graph);
return 0;
}

77
 Breadth First Search implementation in C++:

0 1
6

3 7

2 3
10 4
20
5
4 5
#include<iostream>
using namespace std;
const int N=6;
//initialize matrix to 0
void init(int arr[ ][N])
{
int i,j;
for(i = 0; i < N; i++)
for(j = 0; j < N; j++)
arr[i][j] = 0;
}
//Add edge. set arr[src][dest] = weight
void addEdge(int arr[][N],int src, int dest,int weight)
{
arr[src][dest] = weight;
arr[dest][src] = weight;
}
void printAdjMatrix(int arr[][N])
{
int i, j;
cout<<"The adjacency matrix for the graph:"<<endl<<endl;
for(i = 0; i < N; i++)
{
for(j = 0; j < N; j++)
{
cout<<arr[i][j]<<" ";
}
cout<<endl;
}
}
struct queueType{
int maxQueueSize;
int count;
int Front;

78
int Rear;
int *list; };
void initializeQueue(queueType &curr,int max)
{
curr.Front=0;
curr.Rear=-1;
curr.count=0;
curr.maxQueueSize=max;
curr.list=new int[max];
}
bool isEmpty(queueType &curr)
{
return (curr.count==0);
}
bool isFull(queueType &curr)
{
return (curr.count==curr.maxQueueSize);
}
void addQueue(queueType &curr,int x)
{
if(isFull(curr)==false)
{
curr.Rear=(curr.Rear+1)%curr.maxQueueSize;

curr.count++;
curr.list[curr.Rear]=x;
}
else
cout<<"Full Queue";
}
void deleteQueue(queueType &curr)
{
if(!isEmpty(curr))
{
curr.Front=(curr.Front+1)%curr.maxQueueSize;
curr.count--;
}
else
cout<<"empty Queue";
}
int front(queueType &curr)
{
if(!isEmpty(curr))
return curr.list[curr.Front];
else
cout<<"Empty Queue";

79
}
void print(queueType curr)
{
cout<<"queue elements: ";
while(!isEmpty(curr))
{
cout<<front(curr)<<" ";
deleteQueue(curr);
}
cout<<endl;
}
void BFSGraph(int adjMatrix[][N],int start)
{
queueType Q;
initializeQueue(Q,20);
int visited[N]={0};
visited[start]=1;
addQueue(Q,start);
while (!isEmpty(Q))
{
print(Q);
int current=front(Q);
deleteQueue(Q);
cout<<"visited "<<current<<endl;
for(int i=0;i<N;i++)
{
if(adjMatrix[current][i]!=0 && visited[i]==0)
{
visited[i]=1;
addQueue(Q,i);
}
} }
}
main()
{
int adjMatrix[N][N];
init(adjMatrix);
addEdge(adjMatrix,0,1,6);
addEdge(adjMatrix, 1,2,7);
addEdge(adjMatrix,2, 0, 5);
addEdge(adjMatrix,2, 1, 4);
addEdge(adjMatrix,3, 2, 10);
addEdge(adjMatrix,4, 5, 1);
addEdge(adjMatrix,5, 4, 3);
addEdge(adjMatrix,5,3,6);

80
printAdjMatrix(adjMatrix);
cout<<"enter the start node"<<"\n";
int n; cin>>n;
BFSGraph(adjMatrix,n); }

Eng.\ Maged Albadany

81

You might also like