1. Trang chủ
  2. » Công Nghệ Thông Tin

Bài giảng cấu trúc dữ liệu: danh sách đặc (mảng)

17 356 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 17
Dung lượng 752,64 KB

Nội dung

Tài liệu này dành cho sinh viên, giáo viên khối ngành công nghệ thông tin tham khảo và có những bài học bổ ích hơn, bổ trợ cho việc tìm kiếm tài liệu, giáo án, giáo trình, bài giảng các môn học khối ngành công nghệ thông tin

Trang 1

ðại Học Sư Phạm Tp Hồ Chí Minh

Nội dung

1 ðịnh nghĩa

2 Các phép toán trên mảng

3 Stack

4 Queue

1 ðịnh nghĩa

• Mảng là tập hợp của các biến cùng kiểu ñược

xếp liên tiếp nhau trong bộ nhớ trong.

• Các loại mảng:

– Mảng 1 chiều

• < kiểu dữ liệu > tên_mảng [ số_phần_tử ]

– Mản nhiều chiều

• < kiểu_dữ_liệu > tên_mảng

[ số_phần_tử_chiều_1 ][ số_phần_tử_chiều_2 ]…[ số_phần

_tử_chiều_n ]

2 Các thao tác xử lý cơ bản trên mảng

Bài tập 1 : Viết chương trình nhập vào một dãy số nguyên In dãy số vừa nhập theo thứ tự ngược lại.

Input : số lượng các phần tử trong dãy (N>0).

N số nguyên.

ðối tượng dữ liệu : int N

int a[]

Nhập dãy số Xuất dãy số

Trang 2

# include <iostream.h>

void main() {

cout<<“ n= ” ;

cin>> n;

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

cout<< “ a[“<<i<<”]= ” ;

cin>> a[i];

}

for (i = n-1; i >= 0; i )

cout<< a[i];

}

2 Các thao tác xử lý cơ bản trên mảng

Bài tập 2 : Viết chương trình nhập vào một dãy số nguyên dương In ra dãy số sau khi chèn một phần tử nguyên dương vào một vị trí cho trước của dãy.

Input :

 N là số lượng các phần tử.

 N số nguyên dương

 X là giá trị cần chèn

 K là vị trí cần chèn

Output :

 Dãy số sau khi chèn

ðối tượng dữ liệu:

 int N, X, K

 int A[]

Thao tác xử lý

 Nhập dãy số

 Chèn X vào dãy tại vị trí K

 Xuất dãy số

~ 9 8 5

K

4

X

i

0

N

a) Thao tác chèn 1 phần tử vào mảng

Mô tả

1.Dời các phần tử từ vị trí N-1

ñến K về phía sau 1 ô

2.ðặt giá trị X vào vị trí thứ K

3.Tăng số lượng phần tử

for ( i = N - 1; i >= K ; i ) a[ i+1 ] = a[ i ]

a [ K ] = X ;

N = N +1

2 Các thao tác xử lý cơ bản trên mảng

Bài tập 3 : Viết chương trình nhập vào một dãy số nguyên In

ra dãy số sau khi xóa một phần tử tại một vị trí cho trước của dãy.

Input :

 N là số lượng các phần tử.

 N số nguyên dương

 K là vị trí cần xóa

Output :

 Dãy số sau khi xóa

ðối tượng dữ liệu:

 int N, K

 int A[]

Thao tác xử lý

 Nhập dãy số

 Chèn phần tử tại vị trí K

 Xuất dãy số

Trang 3

3 5 8 9 ~

K

4

i

N

b) Thao tác xóa 1 phần tử của mảng

Mô tả

1.Dời các phần tử từ vị trí K+1

ñến N-1 về phía trước 1 ô

2.Giảm số lượng phần tử ñi 1

for ( i = K; i <= N-2 ; i++) a[ i ] = a[ i+1 ];

N = N -1;

~

2 Các thao tác xử lý cơ bản trên mảng

Bài tập 4 : Viết chương trình nhập vào một dãy số nguyên In

ra vị trí của giá trị X nhập vào từ bàn phím hoặc thông báo không tìm thấy.

Input :

 N là số lượng các phần tử.

 N số nguyên dương

 X là giá trị cần tìm

Output :

 Vị trí của X hoặc thông báo không tìm thấy.

ðối tượng dữ liệu:

 int N, X

 int A[]

Thao tác xử lý

 Nhập dãy số

 Tìm giá tri X

 Xuất thông tin tìm kiếm.

X= 3

4

N

c) Thao tác tìm kiếm tuyến tính

~

Giải thuật

Tiến hành so sánh x lần lượt với phần tử thứ

0, thứ 1,… của mảng cho ñến khi gặp khóa

cần tìm, hoặc hết mảng mà không tìm thấy

giá trị.

c) Thao tác tìm kiếm tuyến tính

1 I = 0   N-1

1.1 Nếu A[i] =X thì

– Print I

– Dừng

2 Nếu I=N thì

print -1

intlinearSearch(inta[ ], int N, intX){

for (int i=0; i<N;i++){

if (a[i] == X) returni

} return -1;

}

X= 3

4

N

~

Trang 4

c) Thao tác tìm kiếm tuyến tính

1.I =0;

2 Trong khi I<N và A[i] !=x thì

tăng i

3 Nếu I=N:

Không tìm thấy

Ngược lại:

Tìm thấy tại vị trí I

int linearSearch(int a[], int N,

int X) {

int i = 0;

while (i<N&& a[i] != X) i++;

//return i==n?-1:i;

if ( i == N ) return -1; else return i;

}

X= 3

4

N

~

c) Thao tác tìm kiếm tuyến tính

1 I =0; A[N] = X

2 Trong khi A[i] !=x thì tăng i.

3 Nếu I=N:

Không tìm thấy.

Ngược lại:

Tìm thấy tại vị trí I

int linearSearch(int a[], int N,

int X) {

int i = 0;

a[N] = X;

While (a[i] != X) i++;

if ( i == N ) return -1; else return i;

}

X= 3

4

N

3

X= 5

1

R

c) Thao tác tìm kiếm nhị phân

~

Giải thuật

Tại mỗi bước tiến hành so sánh X với phần tử

nằm giữa của dãy tìm kiếm hiện hành Dựa vào

kết quả so sánh này ñể quyết ñịnh giới hạn tìm

kiếm ở bước kế tiếp là nữa trên hay nữa dưới

của dãy hiện hành.

c) Thao tác tìm kiếm nhị phân

Bước 1: left = 0; right = N-1; //tìm trên tất cả các phần tử Bước 2: mid = (left + right)/2 ; //lấy mốc ñể so sánh

So sánh a[mid] với x có 3 khả năng

- x=a[mid] : tìm thấy Dừng

- x<a[mid] : left = mid +1 ; //tìm tiếp trong dãy a left …a mid-1

- x>a[mid] : right = mid -1 ; //tìm tiếp trong dãy a mid+1 …a right Bước 3: Nếu left <= right Quay lại bước 2

Ngược lại: Dừng //ñã xét hết tất cả các phần tử

X= 5

1

R

~

Trang 5

c) Thao tác tìm kiếm nhị phân

Bước 1: left = 0; right = N-1; //tìm trên tất cả các phần tử

Bước 2: mid = (left + right)/2 ; //lấy mốc ñể so sánh

So sánh a[mid] với x có 3 khả năng

- x=a[mid] : tìm thấy Dừng

- x<a[mid] : right = mid -1 ; //tìm tiếp trong dãy a left …a mid-1

- x>a[mid] : left= mid +1 ; //tìm tiếp trong dãy a mid+1 …a right

Bước 3: Nếu left <= right Quay lại bước 2

Ngược lại: Dừng //ñã xét hết tất cả các phần tử

X= 4

1

R

~

int left = 0;

int right = n-1;

while (left<=right) {

int mid = (left + right)/2;

if (x == a[mid]) return mid;

if (x < a[mid]) right = mid - 1;

if (x > a[mid]) left = mid + 1;

}

}

Bài tập

1 Viết chương trình tìm phần tử lớn nhất trong một

dãy số nguyên.

2 Viết chương trình tìm tất cả các số nguyên tố trong

một dãy số nguyên dương nhập vào từ bàn phím.

3 Viết chương trình tìm dãy con tăng dần dài nhất

trong dãy số nguyên nhập vào từ bàn phím.

4 Viết chương trình nhập vào một dãy ký tự In ra số

lần xuất hiện của các ký tự trong dãy.

5 Một số tự nhiên ñược gọi là Palindrom khi các chữ

số của nó ñược viết theo thứ tự ngược lại sẽ tạo

thành số mới bằng chính số ñó (ví dụ: 4884, 321123,

15651) Hãy kiểm tra số tự nhiên nhập vào từ bàn

phím có phải là số Palindrom không?

Bài tập

5 ðể sắp xếp dãy số nguyên theo tứ tự tăng dần người ta lần lượt tìm giá trị nhỏ nhất ñặt vào ñầu dãy, giá trị nhỏ thứ 2 ñặt vào vị trí thứ 2, và tương tự như thế cho ñến hết dãy Viết chương trình sắp xếp dãy số nguyên theo ý tưởng trên.

6 Viết chương trình quản lý danh bạ ñiện thoại với các thông tin : Số thứ tự, họ và tên, số ñiện thoại,ñịa chỉ email Chương trình ñảm bảo các chức năng sau:

a Nhập thông tin vào danh bạ

b Danh bạ phải ñược sắp tăng dần theo số thứ tự

c Xuất danh bạ

d Tìm kiếm thông tin dựa vào “họ và tên” hoặc “ñịa chỉ email

e Xóa thông tin dựa vào số thứ tự cho trước.

Trang 6

3 Stack

• Một stack là một cấu trúc

dữ liệu mà việc thêm vào

và loại bỏ ñược thực hiện tại một ñầu (gọi là ñỉnh – top của stack)

• Là một dạng vào sau ra

trước – LIFO ( L ast I n

F irst O ut)

Ví dụ về stack

• Stack rỗng:

• ðẩy (push) Q vào:

• ðẩy A vào:

• Lấy (pop) ra một => ñược A:

• Lấy ra một => ñược Q và stack rỗng:

Q

Q A

Q A

Q

Ứng dụng: ðảo ngược danh sách

• Giải thuật:

1 Lặp lại n lần

1.1 Nhập vào một giá trị

1.2 ðẩy nó vào stack

2 Lặp khi stack chưa rỗng

2.1 Lấy một giá trị từ stack

2.2 In ra

Các phép toán trên ngăn xếp

• empty(A): kiểm tra ngăn xếp có rỗng?

• length(A): Cho biết số phần tử ngăn xếp.

• push(A, x): Thêm phần tử x vào ngăn xếp A.

• pop(A): Loại phần tử ở ñỉnh ngăn xếp.

• getTop(A): Lấy phần tử ở ñỉnh ngăn xếp.

Trang 7

ðảo ngược danh sách – Ví dụ

Cần nhập 4 số vào

Ban ñầu Nhập 1

1

Nhập 5

1 5

Nhập 7

1 5 7

Nhập 3

1 5 7 3

Lấy ra => 3

1

5

7

3

Lấy ra => 7

1 5 7

Lấy ra => 5

1 5

Lấy ra => 1

1

Stack ñã rỗng Ngừng

ðảo ngược danh sách – Mã C++

#include <stack>

using namespace std;

int main( ) { int n;

double item;

stack<double> numbers;

cout << "Bao nhieu so nhap vao? "

cin >> n;

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

cin >> item;

numbers.push(item);

}

while (!numbers.empty( )) {

cout << numbers.top( ) << " ";

numbers.pop( );

} }

sử dụng STL (Standard Template Library)

khai báo một stack có kiểu dữ liệu của các phân tử bên trong là double

ñẩy một số vào trong stack

kiểm tra xem stack có khác rỗng không

lấy giá trị trên ñỉnh của stack ra, stack không ñổi

lấy giá trị trên ñỉnh của stack ra khỏi stack, ñỉnh của stack bây giờ là giá trị kế tiếp

Kiểu trừu tượng (abstract data type)

• ðN1: Một kiểu (type)

– một tập hợp

– mỗi thành phần của tập hợp này là các giá trị (value)

– Ví dụ: int, float, char là các kiểu cơ bản

• ðN2: Một dãy của kiểu T

– có chiều dài bằng 0 là rỗng

– có chiều dài n (n>=1): bộ thứ tự (Sn-1, t)

• Sn-1: dãy có chiều dài n-1 thuộc kiểu T

• t là một giá trị thuộc kiểu T.

Stack trừu tượng

• Một stack kiểu T:

– Một dãy hữu hạn kiểu T – Một số tác vụ:

• 1 Khởi tạo stack rỗng (create)

• 2 Kiểm tra rỗng (empty)

• 3 ðẩy một giá trị vào trên ñỉnh của stack (push)

• 4 Bỏ giá trị ñang có trên ñỉnh của stack (pop)

• 5 Lấy giá trị trên ñỉnh của stack, stack không ñổi (top)

Trang 8

Thiết kế stack

enum Error_code {fail, success, overflow, underflow};

template <class Entry>

class Stack {

public:

Stack(); //constructor

bool empty() const; //kiểm tra rỗng

Error_code push(const Entry &item); //ñẩy item vào

Error_code pop(); //bỏ phần tử trên ñỉnh

Error_code top(Entry &item); //lấy giá trị trên ñỉnh

//khai báo một số phương thức cần thiết khác

private:

//khai báo dữ liệu và hàm phụ trợ chỗ này

};

Thiết kế các phương thức

template <class Entry>

bool Stack<Entry>::empty() const;

Pre: Không có Post: Trả về giá trị true nếu stack hiện tại là rỗng, ngược lại thì trả về false template <class Entry>

Error_code Stack<Entry>::push(const Entry &item);

Pre: Không có Post: Nếu stack hiện tại không ñầy, item sẽ ñược thêm vào ñỉnh của stack Ngược lại trả về giá trị overflow của kiểu Error_code và stack không ñổi template <class Entry>

Error_code Stack<Entry>::pop() const;

Pre: Không có Post: Nếu stack hiện tại không rỗng, ñỉnh của stack hiện tại sẽ bị hủy bỏ

Ngược lại trả về giá trị underflow của kiểu Error_code và stack không ñổi template <class Entry>

Error_code Stack<Entry>::top(Entry &item) const;

Pre: Không có Post: Nếu stack hiện tại không rỗng, ñỉnh của stack hiện tại sẽ ñược chép vào tham biến item Ngược lại trả về giá trị fail của kiểu Error_code.

Hiện thực stack liên tục Khai báo stack liên tục

const int maxstack = 10; //small number for testing

template <class Entry>

class Stack { public:

Stack( );

bool empty( ) const;

Error_code pop( );

Error_code top(Entry &item) const;

Error_code push(const Entry &item);

private:

int count;

Entry entry[maxstack];

};

Trang 9

ðẩy một phần tử vào stack

• Giải thuật:

1 Nếu còn chỗ trống trong stack

1.1 Tăng vị trí ñỉnh lên 1 1.2 Chứa giá trị vào vị trí ñỉnh của stack 1.3 Tăng số phần tử lên 1

top

1 5

7

count=2

Bỏ phần tử trên ñỉnh stack

• Giải thuật:

1 Nếu còn phần tử trong stack

1.1 Giảm vị trí ñỉnh ñi 1 1.2 Giảm số phần tử ñi 1

top

1 5 7

count=3

Thêm/Bỏ phần tử - Mã C++

template <class Entry>

Error_code Stack<Entry>:: push(const Entry &item) {

if (count >= maxstack)

return overflow;

else

entry[count++] = item;

return success;

}

template <class Entry>

Error_code Stack<Entry>:: pop() {

if (count == 0)

return underflow;

else

count ;

return success;

}

Lấy giá trị trên ñỉnh stack

• Giải thuật:

1 Nếu còn phần tử trong stack

1.1 Trả về giá trị tại vị trí ñỉnh

• Mã C++:

template <class Entry>

Error_code Stack<Entry>:: top(Entry &item) {

if (count == 0)

return underflow;

else

item = entry[count - 1];

return success;

}

Trang 10

Ký pháp Ba Lan ñảo

• Mô tả bài toán:

– Các toán hạng ñược ñọc vào trước và ñẩy vào

stack

– Khi ñọc vào toán tử, lấy hai toán hạng ra từ stack,

tính toán với toán tử này, rồi ñẩy kết quả vào stack

• Thiết kế phần mềm:

– Cần một stack ñể chứa toán hạng

– Cần hàm get_command ñể nhận lệnh từ người

dùng

– Cần hàm do_command ñể thực hiện lệnh

Ký pháp Ba Lan ñảo – Thiết kế chức năng

• Tập lệnh:

– ‘? ’: ñọc một giá trị rồi ñẩy vào stack

– Toán tử ‘+ ’, ‘ - ’, ‘ * ’, ‘ / ’: lấy 2 giá trị trong stack, tính toán và ñẩy kết quả vào stack

– Toán tử ‘= ’: in ñỉnh của stack ra

– ‘q ’: kết thúc chương trình

Ký pháp Ba Lan ñảo – Ví dụ

Ban ñầu

Tính toán biểu thức: 3 5 + 2 * =

Toán tử ? Nhập vào 3

3

Toán tử ? Nhập vào 5

3 5

Toán tử + Lấy ra 5 và 3 Tính 3 + 5 => 8

3 5

ðẩy 8 vào

8

Toán tử * Lấy ra 2 và 8 Tính 8 * 2 => 16

8

ðẩy vào 16

16 Toán tử =

In ra 16

16 Toán tử ?

Nhập vào 2

8

16

Ký pháp Ba Lan ñảo - Hàm get_command

char get command( ) { char command;

bool waiting = true;

cout << "Select command and press < Enter > :";

while (waiting) {

cin >> command;

command = tolower(command);

if (command == ‘?’ || command == ‘=‘ || command == ‘+’ ||

command == ‘−’|| command == ‘*’ || command == ‘/’ ||

command == ‘q’) waiting = false;

else {

cout << "Please enter a valid command:" << endl

<< "[?]push to stack [=]print top" <<endl

<< "[+] [−] [*] [/] are arithmetic operations" << endl

<< "[Q]uit." << endl;

} }

return command;

}

Trang 11

Ký pháp Ba Lan ñảo - Giải thuật tính toán

AlgorithmOp_process

Input: toán tử op, stack chứa các toán hạng

Output: stack chứa các toán hạng sau khi tính xong toán tử op

1 Nếu stack không rỗng

1.1 Lấy ñỉnh stack ra thành p

1.2 Bỏ phần tử trên ñỉnh stack

1.3 Nếu stack rỗng

1.3.1 ðẩy p ngược lại

1.3.2 Báo lỗi và thoát

1.4 Lấy ñỉnh stack ra thành q

1.5 Bỏ phần tử trên ñỉnh stack

1.6 Tính toán (q op p)

1.7 ðẩy kết quả vào stack

EndOp_process

Ký pháp Ba Lan ñảo - Toán tử cộng

if (numbers.top(p) == underflow)

cout << "Stack rỗng";

else {

numbers.pop( );

if (numbers.top(q) == underflow) {

cout << "Stack chỉ có 1 trị”;

numbers.push(p);

}

else {

numbers.pop( );

if (numbers.push(q + p) == overflow)

cout << "Stack ñầy”;

} }

Ký pháp Ba Lan ñảo - Chương trình chính

#include "stack.cpp"

//prototype

void introduction( );

void instructions( );

char get_command( );

bool do_command(char command, Stack<double> &numbers);

int main( ) {

Stack<double> stored_numbers;

introduction( );

instructions( );

while (do_command(get_command( ), stored_numbers));

}

//implementation

Ký pháp Ba Lan ñảo - Hàm do_command

bool do_command(char command, Stack &numbers) { double p, q;

switch (command) { case '?’:

cout << "Enter a real number: " << flush; cin >> p;

if (numbers.push(p) == overflow)

cout << "Warning: Stack full, lost number" << endl; break;

case '=‘:

if (numbers.top(p) == underflow) cout << "Stack empty" << endl; else cout << p << endl; break;

// Add options for further user commands.

case ‘q’: cout << "Calculation finished.\n"; return false;

}

return true;

}

Trang 12

4 Queue

• Một queue là một cấu trúc dữ liệu mà các phép toán

thực hiện ở 2 ñỉnh , một ñỉnh gọi là ñầu hàng, một

ñỉnh gọi là cuối hàng.

• Phần tử vào trước sẽ ra trước – FIFO (F irst I n F irst

O ut)

Queue trừu tượng

• Một queue kiểu T:

– Một dãy hữu hạn kiểu T – Một số tác vụ:

• 1 Khởi tạo queue rỗng (create)

• 2 Kiểm tra rỗng (empty)

• 3 Thêm một giá trị vào cuối của queue (append)

• 4 Bỏ giá trị ñang có ở ñầu của queue (serve)

• 5 Lấy giá trị ở ñầu của queue, queue không ñổi

(retrieve)

Thiết kế queue

enum Error_code {fail, success, overflow, underflow};

template <class Entry>

class Queue {

public:

Queue(); //constructor

bool empty() const; //kiểm tra rỗng

Error_code append(const Entry &item); //ñẩy item vào

Error_code serve(); //bỏ 1 phần tử ở ñầu

Error_code retrieve(Entry &item); //lấy giá trị ở ñầu

//khai báo một số phương thức cần thiết khác

private:

//khai báo dữ liệu và hàm phụ trợ chỗ này

};

Thiết kế các phương thức

template <class Entry>

bool Queue<Entry>::empty() const;

Pre: Không có Post: Trả về giá trị true nếu queue hiện tại là rỗng, ngược lại thì trả về false template <class Entry>

Error_code Queue<Entry>::append(const Entry &item);

Pre: Không có Post: Nếu queue hiện tại không ñầy, item sẽ ñược thêm vào cuối của queue Ngược lại trả về giá trị overflow của kiểu Error_code và queue không ñổi template <class Entry>

Error_code Queue<Entry>::serve() const;

Pre: Không có Post: Nếu queue hiện tại không rỗng, ñầu của queue hiện tại sẽ bị hủy bỏ

Ngược lại trả về giá trị underflow của kiểu Error_code và queue không ñổi template <class Entry>

Error_code Queue<Entry>::retrieve(Entry &item) const;

Pre: Không có Post: Nếu queue hiện tại không rỗng, ñầu của queue hiện tại sẽ ñược chép vào tham biến item Ngược lại trả về giá trị underflow của kiểu Error_code.

Ngày đăng: 20/10/2014, 06:52

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w