Giới thiệu thực tiễn về cấu trúc dữ liệu và phân tích thuật toán - Phiên bản 3.2 C

Giới thiệu thực tiễn về cấu trúc dữ liệu và phân tích thuật toán, phiên bản 3.2C, phần 1, cung cấp kiến thức cơ bản và ứng dụng hiệu quả.

Trường đại học

Virginia Tech

Chuyên ngành

Computer Science

Người đăng

Ẩn danh

Thể loại

thesis

2013

247
4
0

Phí lưu trữ

55 Point

Mục lục chi tiết

Preface

1. Data Structures and Algorithms

1.1. A Philosophy of Data Structures

1.1.1. The Need for Data Structures

1.2. Costs and Benefits

1.3. Abstract Data Types and Data Structures

1.4. Problems, Algorithms, and Programs

1.5. Exercises

2. Mathematical Preliminaries

2.1. Sets and Relations

2.2. Proof by Contradiction

2.3. Proof by Mathematical Induction

2.4. Summations and Recurrences

2.5. Exercises

3. Algorithm Analysis

3.1. Best, Worst, and Average Cases

3.2. A Faster Computer, or a Faster Algorithm?

3.3. Calculating the Running Time for a Program

3.4. Speeding Up Your Programs

3.5. Projects

4. Lists, Stacks, and Queues

4.1. Array-Based List Implementation

4.2. Comparison of List Implementations

4.3. Doubly Linked Lists

4.4. Array-Based Stacks

4.5. Comparison of Array-Based and Linked Stacks

4.6. Array-Based Queues

4.7. Comparison of Array-Based and Linked Queues

4.8. Projects

5. Binary Trees

5.1. Definitions and Properties

5.2. The Full Binary Tree Theorem

5.3. A Binary Tree Node ADT

5.4. Binary Tree Traversals

5.5. Binary Tree Node Implementations

5.6. Pointer-Based Node Implementations

5.7. Array Implementation for Complete Binary Trees

5.8. Binary Search Trees

5.9. Heaps and Priority Queues

5.10. Huffman Coding Trees

5.10.1. Building Huffman Coding Trees

5.10.2. Assigning and Using Huffman Codes

5.10.3. Search in Huffman Trees

5.11. Projects

6. Non-Binary Trees

6.1. General Tree Definitions and Terminology

6.2. An ADT for General Tree Nodes

6.3. General Tree Traversals

6.4. The Parent Pointer Implementation

6.5. General Tree Implementations

6.5.1. List of Children

6.5.2. The Left-Child/Right-Sibling Implementation

6.5.3. Dynamic Node Implementations

6.5.4. Dynamic “Left-Child/Right-Sibling” Implementation

6.5.5. Sequential Tree Implementations

6.6. Projects

7. Internal Sorting

7.1. Sorting Terminology and Notation

7.2. Three Θ(n2 ) Sorting Algorithms

7.3. The Cost of Exchange Sorting

7.4. Binsort and Radix Sort

7.5. An Empirical Comparison of Sorting Algorithms

7.6. Lower Bounds for Sorting

7.7. Projects

8. File Processing and External Sorting

8.1. Primary versus Secondary Storage

8.2. Disk Drive Architecture

8.3. Disk Access Costs

8.4. Buffers and Buffer Pools

8.5. The Programmer’s View of Files

8.6. Simple Approaches to External Sorting

9. Searching

9.1. Searching Unsorted and Sorted Arrays

9.2. Self-Organizing Lists

9.3. Bit Vectors for Representing Sets

9.4. Analysis of Closed Hashing

9.5. Tree-based Indexing

10. B+ -Trees

10.1. B+ -Trees

10.2. Projects

11. Graphs

11.1. Terminology and Representations

11.2. Depth-First Search

11.3. Breadth-First Search

11.4. Shortest-Paths Problems

11.4.1. Single-Source Shortest Paths

11.5. Minimum-Cost Spanning Trees

11.6. Projects

12. Lists and Arrays Revisited

12.1. Dynamic Storage Allocation

12.2. Failure Policies and Garbage Collection

12.3. Projects

13. Advanced Tree Structures

13.1. Tries

13.2. The AVL Tree

13.3. The Splay Tree

13.4. Spatial Data Structures

13.4.1. The PR quadtree

13.4.2. Other Point Data Structures

13.4.3. Other Spatial Data Structures

13.5. Projects

14. Analysis Techniques

14.1. Estimating Upper and Lower Bounds

14.2. Divide and Conquer Recurrences

14.3. Average-Case Analysis of Quicksort

14.4. Projects

15. Lower Bounds

15.1. Introduction to Lower Bounds Proofs

15.2. Lower Bounds on Searching Lists

15.2.1. Searching in Unsorted Lists

15.2.2. Searching in Sorted Lists

15.3. Finding the Maximum Value

15.4. Adversarial Lower Bounds Proofs

15.5. State Space Lower Bounds Proofs

15.6. Finding the ith Best Element

15.7. Projects

16. Patterns of Algorithms

16.1. The Knapsack Problem

16.2. All-Pairs Shortest Paths

16.3. Randomized algorithms for finding large values

16.4. Largest Common Factor

16.5. The Fast Fourier Transform

16.6. Projects

17. Limits to Computation

17.1. The Theory of N P-Completeness

17.2. The Halting Problem Is Unsolvable

17.3. Coping with N P-Complete Problems

17.4. Projects

Utility Functions

Bibliography

Index

Tóm tắt

I. Giới thiệu thực tiễn về cấu trúc dữ liệu và phân tích thuật toán

Cấu trúc dữ liệu và phân tích thuật toán là hai khái niệm cốt lõi trong lập trình và phát triển phần mềm. Chúng giúp lập trình viên tổ chức và xử lý dữ liệu một cách hiệu quả. Việc hiểu rõ về cấu trúc dữ liệuthuật toán không chỉ giúp tối ưu hóa hiệu suất chương trình mà còn nâng cao khả năng giải quyết vấn đề. Phiên bản 3.2 C của tài liệu này cung cấp cái nhìn sâu sắc về các khái niệm này.

1.1. Tổng quan về cấu trúc dữ liệu

Cấu trúc dữ liệu là cách tổ chức và lưu trữ dữ liệu để có thể sử dụng hiệu quả. Các loại cấu trúc dữ liệu phổ biến bao gồm danh sách, ngăn xếp, hàng đợi và cây. Mỗi loại có ưu điểm và nhược điểm riêng, phù hợp với các tình huống khác nhau trong lập trình.

1.2. Tầm quan trọng của phân tích thuật toán

Phân tích thuật toán giúp đánh giá hiệu suất của các thuật toán khác nhau. Điều này bao gồm việc xác định thời gian chạy và mức tiêu thụ bộ nhớ. Việc phân tích này rất quan trọng để chọn lựa thuật toán phù hợp cho từng bài toán cụ thể.

II. Vấn đề và thách thức trong cấu trúc dữ liệu và thuật toán

Mặc dù có nhiều lợi ích, việc lựa chọn và triển khai cấu trúc dữ liệuthuật toán cũng gặp phải nhiều thách thức. Các lập trình viên thường phải đối mặt với các vấn đề như hiệu suất, khả năng mở rộng và tính dễ bảo trì của mã nguồn. Những thách thức này cần được giải quyết để đảm bảo rằng phần mềm hoạt động hiệu quả trong môi trường thực tế.

2.1. Các vấn đề hiệu suất

Một trong những vấn đề lớn nhất là hiệu suất của thuật toán. Các thuật toán khác nhau có thể có thời gian chạy khác nhau, và việc chọn sai thuật toán có thể dẫn đến hiệu suất kém. Việc phân tích thời gian chạy là cần thiết để tránh những vấn đề này.

2.2. Khả năng mở rộng

Khi dữ liệu tăng lên, cấu trúc dữ liệu cần phải có khả năng mở rộng. Một số cấu trúc dữ liệu có thể không hoạt động tốt khi kích thước dữ liệu lớn. Điều này đòi hỏi lập trình viên phải cân nhắc kỹ lưỡng khi thiết kế hệ thống.

III. Phương pháp tối ưu hóa thuật toán trong lập trình C

Tối ưu hóa thuật toán là một phần quan trọng trong việc phát triển phần mềm. Việc áp dụng các phương pháp tối ưu hóa có thể giúp cải thiện đáng kể hiệu suất của chương trình. Trong ngôn ngữ lập trình C, có nhiều kỹ thuật có thể được sử dụng để tối ưu hóa thuật toán.

3.1. Sử dụng thuật toán hiệu quả

Lựa chọn thuật toán phù hợp là bước đầu tiên trong tối ưu hóa. Các thuật toán như QuickSort và MergeSort thường được ưa chuộng vì hiệu suất tốt hơn so với các thuật toán sắp xếp đơn giản khác.

3.2. Tối ưu hóa bộ nhớ

Quản lý bộ nhớ hiệu quả là rất quan trọng trong lập trình C. Việc sử dụng con trỏ và cấp phát động có thể giúp tiết kiệm bộ nhớ và cải thiện hiệu suất của chương trình.

IV. Ứng dụng thực tiễn của cấu trúc dữ liệu và thuật toán

Cấu trúc dữ liệu và thuật toán không chỉ là lý thuyết mà còn có nhiều ứng dụng thực tiễn trong các lĩnh vực khác nhau. Từ phát triển phần mềm đến phân tích dữ liệu, việc áp dụng đúng các khái niệm này có thể mang lại giá trị lớn cho doanh nghiệp.

4.1. Ứng dụng trong phát triển phần mềm

Trong phát triển phần mềm, việc sử dụng đúng cấu trúc dữ liệu có thể giúp cải thiện hiệu suất và khả năng bảo trì của mã nguồn. Các lập trình viên cần nắm vững các cấu trúc dữ liệu để xây dựng ứng dụng hiệu quả.

4.2. Phân tích dữ liệu lớn

Trong lĩnh vực phân tích dữ liệu, các thuật toán như tìm kiếm và sắp xếp là rất quan trọng. Việc áp dụng các thuật toán này giúp xử lý và phân tích dữ liệu lớn một cách nhanh chóng và hiệu quả.

V. Kết luận và tương lai của cấu trúc dữ liệu và thuật toán

Cấu trúc dữ liệu và thuật toán sẽ tiếp tục đóng vai trò quan trọng trong phát triển công nghệ. Với sự phát triển của trí tuệ nhân tạo và học máy, nhu cầu về các thuật toán hiệu quả và cấu trúc dữ liệu tối ưu sẽ ngày càng tăng. Việc nắm vững các khái niệm này là cần thiết cho các lập trình viên trong tương lai.

5.1. Xu hướng phát triển

Các xu hướng mới trong công nghệ như trí tuệ nhân tạo và học máy đang tạo ra nhu cầu mới cho các thuật toán và cấu trúc dữ liệu. Lập trình viên cần cập nhật kiến thức để theo kịp sự phát triển này.

5.2. Tầm quan trọng của việc học tập liên tục

Việc học tập liên tục về cấu trúc dữ liệu và thuật toán là rất quan trọng. Các lập trình viên cần tham gia các khóa học và nghiên cứu để nâng cao kỹ năng và kiến thức của mình.

Tóm tắt và mô tả trên trang này được tạo với sự hỗ trợ của AI từ nội dung tài liệu gốc; tài liệu do người dùng đóng góp và được kiểm duyệt trước khi xuất bản. Báo lỗi nội dung.

17/07/2025
A practical introduction to data structures and algorithm analysis edition 3 2 c version part 1

Trích đoạn nội dung tài liệu

A Practical Introduction to Data Structures and Algorithm Analysis Edition 3. Shaffer Department of Computer Science Virginia Tech Blacksburg, VA 24061 March 28, 2013 Update 3.10 For a list of changes, see http://people.edu/˜shaffer/Book/errata.html Copyright © 2009-2012 by Clifford A. This document is made freely available in PDF form for educational and other non-commercial use. You may make copies of this file and redistribute in electronic form without charge.

You may extract portions of this document provided that the front page, including the title, author, and this notice are included. Any commercial use of this document requires the written consent of the author. The author can be reached at shaffer@cs. If you wish to have a printed version of this document, print copies are published by Dover Publications (see http://store.

Further information about this text is available at http://people.edu/˜shaffer/Book/. Contents Preface xiii I Preliminaries 1 1 Data Structures and Algorithms 3 1.1 A Philosophy of Data Structures 4 1.1 The Need for Data Structures 4 1.2 Costs and Benefits 6 1.2 Abstract Data Types and Data Structures 8 1.4 Problems, Algorithms, and Programs 16 1.6 Exercises 20 2 Mathematical Preliminaries 25 2.1 Sets and Relations 25 2.4 Summations and Recurrences 32 2.6 Mathematical Proof Techniques 38 iii iv Contents 2.2 Proof by Contradiction 39 2.3 Proof by Mathematical Induction 40 2.9 Exercises 48 3 Algorithm Analysis 55 3.2 Best, Worst, and Average Cases 61 3.3 A Faster Computer, or a Faster Algorithm? 62 3.5 Calculating the Running Time for a Program 71 3.10 Speeding Up Your Programs 82 3.14 Projects 90 II Fundamental Data Structures 93 4 Lists, Stacks, and Queues 95 4.1 Array-Based List Implementation 100 4.3 Comparison of List Implementations 112 Contents v 4.5 Doubly Linked Lists 115 4.1 Array-Based Stacks 121 4.3 Comparison of Array-Based and Linked Stacks 123 4.1 Array-Based Queues 128 4.3 Comparison of Array-Based and Linked Queues 133 4.7 Projects 148 5 Binary Trees 151 5.1 Definitions and Properties 151 5.1 The Full Binary Tree Theorem 153 5.2 A Binary Tree Node ADT 155 5.2 Binary Tree Traversals 155 5.3 Binary Tree Node Implementations 160 5.1 Pointer-Based Node Implementations 160 5.3 Array Implementation for Complete Binary Trees 168 5.4 Binary Search Trees 168 5.5 Heaps and Priority Queues 178 5.6 Huffman Coding Trees 185 5.1 Building Huffman Coding Trees 186 5.2 Assigning and Using Huffman Codes 192 5.3 Search in Huffman Trees 195 5.9 Projects 200 6 Non-Binary Trees 203 vi Contents 6.1 General Tree Definitions and Terminology 203 6.1 An ADT for General Tree Nodes 204 6.2 General Tree Traversals 205 6.2 The Parent Pointer Implementation 207 6.3 General Tree Implementations 213 6.1 List of Children 214 6.2 The Left-Child/Right-Sibling Implementation 215 6.3 Dynamic Node Implementations 215 6.4 Dynamic “Left-Child/Right-Sibling” Implementation 218 6.5 Sequential Tree Implementations 219 6.8 Projects 226 III Sorting and Searching 229 7 Internal Sorting 231 7.1 Sorting Terminology and Notation 232 7.2 Three Θ(n2 ) Sorting Algorithms 233 7.4 The Cost of Exchange Sorting 238 7.7 Binsort and Radix Sort 252 7.8 An Empirical Comparison of Sorting Algorithms 259 7.9 Lower Bounds for Sorting 261 7.12 Projects 269 Contents vii 8 File Processing and External Sorting 273 8.1 Primary versus Secondary Storage 273 8.1 Disk Drive Architecture 276 8.2 Disk Access Costs 280 8.3 Buffers and Buffer Pools 282 8.4 The Programmer’s View of Files 290 8.1 Simple Approaches to External Sorting 294 8.1 Searching Unsorted and Sorted Arrays 312 9.2 Self-Organizing Lists 317 9.3 Bit Vectors for Representing Sets 323 9.4 Analysis of Closed Hashing 339 9.3 Tree-based Indexing 358 10.1 B+ -Trees 368 viii Contents 10.8 Projects 377 IV Advanced Data Structures 379 11 Graphs 381 11.1 Terminology and Representations 382 11.1 Depth-First Search 393 11.2 Breadth-First Search 394 11.4 Shortest-Paths Problems 399 11.1 Single-Source Shortest Paths 400 11.5 Minimum-Cost Spanning Trees 402 11.8 Projects 412 12 Lists and Arrays Revisited 415 12.1 Dynamic Storage Allocation 424 12.2 Failure Policies and Garbage Collection 431 12.6 Projects 437 13 Advanced Tree Structures 439 13.1 Tries 439 Contents ix 13.1 The AVL Tree 445 13.2 The Splay Tree 447 13.3 Spatial Data Structures 450 13.2 The PR quadtree 457 13.3 Other Point Data Structures 461 13.4 Other Spatial Data Structures 463 13.6 Projects 465 V Theory of Algorithms 469 14 Analysis Techniques 471 14.1 Estimating Upper and Lower Bounds 477 14.3 Divide and Conquer Recurrences 482 14.4 Average-Case Analysis of Quicksort 484 14.6 Projects 493 15 Lower Bounds 495 15.1 Introduction to Lower Bounds Proofs 496 15.2 Lower Bounds on Searching Lists 498 15.1 Searching in Unsorted Lists 498 15.2 Searching in Sorted Lists 500 15.3 Finding the Maximum Value 501 15.4 Adversarial Lower Bounds Proofs 503 15.5 State Space Lower Bounds Proofs 506 15.6 Finding the ith Best Element 509 x Contents 15.10Projects 517 16 Patterns of Algorithms 519 16.1 The Knapsack Problem 521 16.2 All-Pairs Shortest Paths 523 16.1 Randomized algorithms for finding large values 525 16.2 Largest Common Factor 533 16.5 The Fast Fourier Transform 537 16.6 Projects 543 17 Limits to Computation 545 17.1 The Theory of N P-Completeness 553 17.3 Coping with N P-Complete Problems 562 17.2 The Halting Problem Is Unsolvable 569 17.6 Projects 574 Contents xi VI APPENDIX 577 A Utility Functions 579 Bibliography 581 Index 587 Preface We study data structures so that we can learn to write more efficient programs. But why must programs be efficient when new computers are faster every year? The reason is that our ambitions grow with our capabilities. Instead of rendering efficiency needs obsolete, the modern revolution in computing power and storage capability merely raises the efficiency stakes as we attempt more complex tasks.

The quest for program efficiency need not and should not conflict with sound design and clear coding. Creating efficient programs has little to do with “program- ming tricks” but rather is based on good organization of information and good al- gorithms. A programmer who has not mastered the basic principles of clear design is not likely to write efficient programs. Conversely, concerns related to develop- ment costs and maintainability should not be used as an excuse to justify inefficient performance.

Generality in design can and should be achieved without sacrificing performance, but this can only be done if the designer understands how to measure performance and does so as an integral part of the design and implementation pro- cess. Most computer science curricula recognize that good programming skills be- gin with a strong emphasis on fundamental software engineering principles. Then, once a programmer has learned the principles of clear program design and imple- mentation, the next step is to study the effects of data organization and algorithms on program efficiency. Approach: This book describes many techniques for representing data.

These techniques are presented within the context of the following principles: 1. Each data structure and each algorithm has costs and benefits. Practitioners need a thorough understanding of how to assess costs and benefits to be able to adapt to new design challenges. This requires an understanding of the principles of algorithm analysis, and also an appreciation for the significant effects of the physical medium employed (e., data stored on disk versus main memory).

Related to costs and benefits is the notion of tradeoffs. For example, it is quite common to reduce time requirements at the expense of an increase in space requirements, or vice versa. Programmers face tradeoff issues regularly in all xiii xiv Preface phases of software design and implementation, so the concept must become deeply ingrained. Programmers should know enough about common practice to avoid rein- venting the wheel.

Thus, programmers need to learn the commonly used data structures, their related algorithms, and the most frequently encountered design patterns found in programming. Data structures follow needs. Programmers must learn to assess application needs first, then find a data structure with matching capabilities. To do this requires competence in Principles 1, 2, and 3.

As I have taught data structures through the years, I have found that design issues have played an ever greater role in my courses. This can be traced through the various editions of this textbook by the increasing coverage for design patterns and generic interfaces. The first edition had no mention of design patterns. The second edition had limited coverage of a few example patterns, and introduced the dictionary ADT and comparator classes.

With the third edition, there is explicit coverage of some design patterns that are encountered when programming the basic data structures and algorithms covered in the book. Using the Book in Class: Data structures and algorithms textbooks tend to fall into one of two categories: teaching texts or encyclopedias. Books that attempt to do both usually fail at both. This book is intended as a teaching text.

I believe it is more important for a practitioner to understand the principles required to select or design the data structure that will best solve some problem than it is to memorize a lot of textbook implementations. Hence, I have designed this as a teaching text that covers most standard data structures, but not all. A few data structures that are not widely adopted are included to illustrate important principles. Some relatively new data structures that should become widely used in the future are included.

Within an undergraduate program, this textbook is designed for use in either an advanced lower division (sophomore or junior level) data structures course, or for a senior level algorithms course. New material has been added in the third edition to support its use in an algorithms course. Normally, this text would be used in a course beyond the standard freshman level “CS2” course that often serves as the initial introduction to data structures. Readers of this book should typically have two semesters of the equivalent of programming experience, including at least some exposure to C++.

Readers who are already familiar with recursion will have an advantage. Students of data structures will also benefit from having first completed a good course in Discrete Mathematics. Nonetheless, Chapter 2 attempts to give a reasonably complete survey of the prerequisite mathematical topics at the level necessary to understand their use in this book. Readers may wish to refer back to the appropriate sections as needed when encountering unfamiliar mathematical material.

Preface xv A sophomore-level class where students have only a little background in basic data structures or analysis (that is, background equivalent to what would be had from a traditional CS2 course) might cover Chapters 1-11 in detail, as well as se- lected topics from Chapter 13. That is how I use the book for my own sophomore- level class. Students with greater background might cover Chapter 1, skip most of Chapter 2 except for reference, briefly cover Chapters 3 and 4, and then cover chapters 5-12 in detail. Again, only certain topics from Chapter 13 might be cov- ered, depending on the programming assignments selected by the instructor.

A senior-level algorithms course would focus on Chapters 11 and 14-17. Chapter 13 is intended in part as a source for larger programming exercises. I recommend that all students taking a data structures course be required to im- plement some advanced tree structure, or another dynamic structure of comparable difficulty such as the skip list or sparse matrix representations of Chapter 12. None of these data structures are significantly more difficult to implement than the binary search tree, and any of them should be within a student’s ability after completing Chapter 5.

While I have attempted to arrange the presentation in an order that makes sense, instructors should feel free to rearrange the topics as they see fit. The book has been written so that once the reader has mastered Chapters 1-6, the remaining material has relatively few dependencies. Clearly, external sorting depends on understand- ing internal sorting and disk files.2 on the UNION/FIND algorithm is used in Kruskal’s Minimum-Cost Spanning Tree algorithm.2 on self- organizing lists mentions the buffer replacement schemes covered in Section 8. Chapter 14 draws on examples from throughout the book.

Nội dung được bảo vệ bản quyền — Tải xuống đầy đủ

Tài liệu "Giới thiệu thực tiễn về cấu trúc dữ liệu và phân tích thuật toán - Phiên bản 3.2 C" cung cấp một cái nhìn tổng quan về các khái niệm cơ bản trong cấu trúc dữ liệu và phân tích thuật toán, giúp người đọc nắm bắt được các nguyên lý quan trọng trong lập trình và phát triển phần mềm. Tài liệu này không chỉ giải thích các cấu trúc dữ liệu phổ biến như danh sách, ngăn xếp, hàng đợi, và cây, mà còn phân tích hiệu suất của các thuật toán liên quan, từ đó giúp người đọc hiểu rõ hơn về cách tối ưu hóa mã nguồn.

Để mở rộng kiến thức của bạn, bạn có thể tham khảo tài liệu Giáo trình cấu trúc dữ liệu và giải thuật ngành nghề công nghệ thông tin trình độ cao đẳng, nơi cung cấp cái nhìn sâu hơn về ứng dụng của cấu trúc dữ liệu trong ngành công nghệ thông tin. Ngoài ra, tài liệu Giáo trình cấu trúc dữ liệu và giải thuật nhiều tác giả sẽ giúp bạn tiếp cận với nhiều quan điểm khác nhau từ các chuyên gia trong lĩnh vực này. Cuối cùng, bạn cũng có thể tìm hiểu thêm qua tài liệu Giáo trình cấu trúc dữ liệu và thuật toán tái bản phần 1, nơi cung cấp kiến thức nền tảng vững chắc về cấu trúc dữ liệu và thuật toán.

Những tài liệu này không chỉ giúp bạn củng cố kiến thức mà còn mở ra nhiều cơ hội để khám phá sâu hơn về lĩnh vực này.