当前位置:首页 >> >>

The Evolution of Data Structures


Session S3H

The Evolution of Data Structures
James Harris1and Ardian Greca2 Georgia Southern University, Department of Computer Science P.O. Box 7997, Statesboro, GA 30460

Abstract - For over 20 years, the data structures course has been a pillar of computer science programs at colleges and universities. This paper looks at how the data structures course has evolved over time from a course that emphasized algorithmic concepts to a course that emphasizes syntactical and design concepts. It illustrates how the evolution of programming languages and concepts can introduce “gratuitous” complexity into algorithms. Specific algorithms and abstract data types are compared in past and present data structures texts using a suite of software metrics. A comparison is performed between algorithms from data structures texts across different programming languages and across procedural and object oriented paradigms. The results are compared to provide evidence of how the course has evolved over time. Index Terms – Abstract Data Types, Data Structures, Software Metrics, Syntactic Complexity. INTRODUCTION The data structures course has been a core constituent for many years in computer science programs. While spanning many languages, from FORTRAN to Pascal to C to C++ and now Java, the basic content of the course has remained unchanged. As languages have evolved, there has been a perceived increased in the syntactic complexity of data structures to become obscured. Many object oriented features seem to add to the syntactic complexity without contributing to the functionality of an algorithm. Students are required to learn more complex language syntax and very often the underlying algorithm is lost in the confusion. The term “gratuitous complexity” was first described in [1] as complexity that “contributes nothing to the task in hand”. For example, in the book “Data Structures and Algorithm Analysis in C++” by Mark Allen Weiss[11], Weiss defines a Node for a linked list in C++ as: template <class Object> class ListNode { ListNode( const Object & theElement = Object( ), ListNode * n = NULL ) : element( theElement ), next( n ) { } Object element;
1 2

ListNode *next; friend class List<Object>; friend class ListItr<Object>; };
FIGURE I A LINKED LIST NODE IMPLEMENTED IN C++

In this small segment of C++ code, there are classes, objects, templates, constructors, default arguments that are used in calls to other data member’s constructors and friend class declarations which are passed the underlying template type of the ListNode class. Couldn’t the functionality be expressed in a way that does not obscure the underlying process? In an earlier book by Weiss, “Data Structures and Algorithm Analysis” [10], a node for a linked list is defined in the “C” language as follows: typedef struct Node *PtrToNode; typedef PtrToNode Position; struct Node { ElementType Element; Position Next; };
FIGURE II A LINKED LIST NODE IMPLEMENTED IN C

There is more functionality in Weiss’s C++ version of a node, but how much of the added complexity is gratuitous? For example, in C a node “N” could be initialized as follows: N.element.field1 = initvalue1; N.element.field2 = initvalue2; etc. This is straightforward and students do not have to focus on understanding a large number of abstract programming concepts in order to comprehend the underlying process. Of course, the fault could be placed on the author. Clever use of syntax very often obscures the underlying process. In his book “Data Structures and Algorithm Analysis in Java” [12], Weiss defines a node for a linked list as follows:

James Harris, Associate Professor of Computer Science, jkharris@georgiasouthern.edu Ardian Greca, Assistant Professor of Computer Science, naidrag@IEEE.org

0-7803-8552-7/04/$20.00 ? 2004 IEEE October 20 – 23, 2004, Savannah, GA 34th ASEE/IEEE Frontiers in Education Conference S3H-9

Session S3H
class ListNode { // Constructors ListNode( Object theElement ) { this( theElement, null ); } ListNode( Object theElement, ListNode n ) { element = theElement; next = n; } // Friendly data; accessible by other package routines Object element; ListNode next; }
FIGURE III A LINKED LIST NODE IMPLEMENTED IN JAVA

template <class Entry> class Binary_tree { public: Binary_tree(); protected: Binary_node<Entry> *root; }; template <class Entry> struct Binary_node { Entry data; Binary_node<Entry> *left; Binary_node<Entry> *right; Binary_node(); }; template <class Entry> Binary_tree<Entry>::Binary_tree() { root = NULL; }
FIGURE V A BINARY TREE DEFINITION IN C++

The code in Figure III is considerably more comprehendible than the corresponding C++ code, albeit without templates. One of the issues with implementing abstract data types (ADT’s) with object oriented languages is the question of obscuring the algorithm by using more sophisticated language constructs needed to implement objects. As the previous example illustrates, this does not necessarily have to be the case. As another example, consider Dale Kruse’s Pascal and C++ definitions for a binary tree ADT [2,4].

These definitions include the data definitions and the implementation of a C++ default constructor and its equivalent in Pascal. Clearly the C++ definition is longer and more complex. Part of the adding complexity stems from the fact that in the C++ version, a tree is defined by a class rather than just a pointer variable as in Pascal. In fact, much of the added complexity in implementing ADT’s in object oriented languages can be attributed to the use of objects rather than pointers to represent ADT’s. Most books in C++ allow for dynamic declarations such as: Binary Tree T(100); This creates the need for copy constructors and destructors. It also allows objects to be passed to and from methods by value, something that could not be done using the pointer representation. Objects are now being created and destroyed implicitly further adding to the confusion. Java has removed the need for dynamic memory management and I believe this has helped reduce the gratuitous complexity associated with objects in C++. Many more examples of gratuitous complexity can be found in both older and newer data structures textbooks across a variety of programming languages. The question is “Is gratuitous complexity increasing as languages evolve?” To help shed some light on this situation, an objective measure of syntactic complexity is applied to ADT’s defined in various textbooks over time to see if a trend can be found. TESTING THE HYPOTHESIS In order to test the hypothesis that syntactic complexity has increased in data structures courses as languages have

type treepointer = ^treenode; treenode = record entry: treeentry; left, right: treepointer end

function TreeEmpty(root: treepointer): Boolean; begin TreeEmpty := (root =nil) end;
FIGURE IV A BINARY TREE DEFINITION IN C

0-7803-8552-7/04/$20.00 ? 2004 IEEE October 20 – 23, 2004, Savannah, GA 34th ASEE/IEEE Frontiers in Education Conference S3H-10

Session S3H
evolved, an objective measure of complexity is needed along with a representative sample of the implementations of ADT’s. A set of four ADT’s from nine data structures texts ([2]-[4], [6]-[8], [10]-[12]) were analyzed using software metrics in an attempt to measure syntactic complexity. The textbooks used in this study are categorized in Table I below:

TABLE I TEXTBOOKS USED IN THE STUDY

Title Pascal Plus Data Structures C++ Plus Data Structures Object Oriented Data Structures using Java Data Structures Program Design Data Structure and Program Design in C Data Structures and Program Design in C++ Data Structures and Algorithm Analysis in Java Data Structures and Algorithm Analysis in C++ Data Structures and Algorithm Analysis in Java

Author(s) Nell B. Dale, Neil Dale, Susan C. Lilly Nell B. Dale Nell Dale, Daniel T. Joyce, Chip Weems Robert L. Kruse Robert L. Kruse, Bruce P. Leung, Clovis L. Tondo Robert L. Kruse , Alex Ryba Mark Allen Weiss Mark Allen Weiss Mark Allen Weiss

These books were chosen because they involve three authors (Dale, Kruse, and Weiss), who have published over time various data structures books in different languages. The functionality within each ADT tends to be consistent within authors, i.e. independent of the implementation language. Another reason these texts were chosen is because each of these authors was nice enough to make copies of their source code available online [13]-[15]. The four ADT’s analyzed are common to most data structures textbooks. They are stacks (implemented with arrays), circular queues (also implemented with arrays), singly linked lists, and binary search trees. Each set of source code was first stripped of comments and blank lines. The following seven metrics were measured: ? ? ? ? ? ? ? Number of characters Number of tokens Number of lines Number of blocks (BC) Number of weighted blocks (WBC) Number of different identifiers (D-Ident) Number of different reserved words (D-RW)

The number of characters, tokens, and lines generally indicates the amount of code needed for implementation. In general, the more code needed to implement an algorithm, the greater the syntactic complexity. The number of blocks or block count (BC) is a measure of logical “blocks” of code. Blocks are logical groupings of statements used by other syntactic structures. Blocks are determined by BEGIN and END statements in Pascal (with several exceptions) and “{“ and “}” in C, C++, and Java. Weighted blocks assign a weight to each block that is the nesting level of that block. For example, if a block is nested within two other blocks, it has a nesting level of three and

therefore a weight of three. The weighted block count (WBC), which is the sum of the weighted blocks, is a good measure of complexity since each level of nesting applies an addition scoping and control context, adding to the complexity of an algorithm. The number of different identifiers (D-Ident) requires the reader to remember the name and purpose of each identifier. A program with many identifiers is analogous to going to a meeting where you are introduced to many people. It becomes difficult to associate names with faces. As a measure of complexity, the number of different reserved words (D-RW) differs from the number of identifiers. In order to understand an implementation with a greater number of reserved words, the reader must have a greater knowledge of language syntax. The number of identifiers and the number of reserved words were not included as measures because they are a subset of the number of tokens. Remembering the purpose of an identifier involves associating a particular variable or a function with its purpose, whereas remembering the purpose of a reserved word involves grammatical syntax such as flow of control, primitive data types, etc. Several common complexity measures, such as cyclomatic numbers [5] and Halstead measures [9] were not deemed appropriate because they tend to measure algorithmic complexity rather than syntactic complexity. Table II shows the results of the metrics applied to the sample code. ADT stands for “Abstract Data Type”, BST stands for “Binary Search Tree”, “LL” stands for “Linked Lists”, PAS stands for Pascal, and AVG stands for “Average”. The data in Table II is sorted by the primary key “Author”, secondary key “ADT”, and tertiary key “Language”. The data is grouped by Author first and ADT second.

0-7803-8552-7/04/$20.00 ? 2004 IEEE October 20 – 23, 2004, Savannah, GA 34th ASEE/IEEE Frontiers in Education Conference S3H-11

Session S3H
TABLE II MEASURE COUNTS Author DALE DALE DALE ADT BST BST BST Language C++ JAVA PAS AVG JAVA PAS C++ AVG C++ JAVA PAS AVG C++ JAVA PAS AVG C C++ PAS AVG C C++ PAS AVG C C++ PAS AVG C C++ PAS AVG C C++ JAVA AVG C C++ JAVA AVG C C++ JAVA AVG C C++ JAVA AVG Chars 1661 3384 3097 2714 1618 2556 1974 2049.33 1359 749 1161 1089.67 804 1218 1262 1094.67 3217 4374 3079 3556.67 2651 3461 1761 2624.33 782 697 796 758.333 852 696 605 717.667 1676 4957 2557 3063.33 1705 2791 1981 2159 1547 1240 1049 1278.67 1374 1123 963 1153.33 Tokens 467 844 676 662.33 369 588 507 488 386 212 253 283.67 237 258 290 261.67 1094 1189 625 969.33 795 978 563 778.67 266 225 238 243 273 204 188 221.67 550 1347 783 893.33 572 863 526 653.67 507 359 309 391.67 410 325 285 340 Lines 88 203 185 158.67 103 141 108 117.33 90 49 62 67 52 75 71 66 175 187 172 178 140 167 101 136 52 44 48 48 60 48 36 48 123 229 153 168.33 136 142 120 132.67 121 79 74 91.333 98 71 66 78.333 BC 11 33 26 23.33 17 18 14 16.33 11 8 8 9 7 15 10 10.67 30 28 23 27 24 20 18 20.67 9 6 10 8.333 12 6 9 9 13 29 24 22 17 23 22 20.67 15 9 13 12.33 11 9 13 11 WBC 16 76 66 52.67 37 44 16 32.33 13 14 15 14 7 27 27 20.33 46 37 57 46.67 43 26 47 38.67 11 6 13 10 14 6 19 13 19 35 49 34.33 20 31 43 31.33 19 9 27 18.33 12 9 27 16 D-Ident 37 54 52 47.667 34 39 22 31.667 17 15 26 19.333 14 22 34 23.333 45 44 48 45.667 23 40 37 33.333 16 14 27 19 19 13 23 18.333 22 29 36 29 29 34 51 38 27 20 29 25.333 26 18 27 23.667 D-RW 17 18 12 15.667 20 16 14 16.667 16 12 10 12.667 11 20 11 14 12 17 17 15.333 10 15 22 15.667 8 8 15 10.333 9 11 15 11.667 8 19 19 15.333 8 18 18 14.667 9 12 20 13.667 8 12 20 13.333

DALE DALE DALE

LL LL LL

DALE DALE DALE

QUEUE QUEUE QUEUE

DALE DALE DALE

STACK STACK STACK

KRUSE KRUSE KRUSE

BST BST BST

KRUSE KRUSE KRUSE

LL LL LL

KRUSE KRUSE KRUSE

QUEUE QUEUE QUEUE

KRUSE KRUSE KRUSE

STACK STACK STACK

WEISS WEISS WEISS

BST BST BST

WEISS WEISS WEISS

LL LL LL

WEISS WEISS WEISS

QUEUE QUEUE QUEUE

WEISS WEISS WEISS

STACK STACK STACK

0-7803-8552-7/04/$20.00 ? 2004 IEEE October 20 – 23, 2004, Savannah, GA 34th ASEE/IEEE Frontiers in Education Conference S3H-12

Session S3H
Since each author has implemented different functionality for a particular data structure, the values in Table II were normalized by dividing each value by the corresponding average value for a particular author and data structure. Because the functionality of each author’s data structure does not vary by author over the implementation language, dividing each count by the corresponding average gives a measure that allows a comparison between languages independent of the differing functionalities provided by each author. The data was then sorted by primary key “Language” (Lang) and secondary key “ADT”. The results are shown in Table III.

TABLE III WEIGHTED MEASURE COUNTS Author KRUSE WEISS KRUSE WEISS KRUSE WEISS KRUSE WEISS ADT BST BST LL LL QUEUE QUEUE STACK STACK Lang C C C C C C C C Avg C++ C++ C++ C++ C++ C++ C++ C++ C++ C++ C++ C++ Avg JAVA JAVA JAVA JAVA JAVA JAVA JAVA JAVA Avg PAS PAS PAS PAS PAS PAS PAS PAS Avg Chars 0.904 0.547 1.010 0.790 1.031 1.210 1.187 1.191 0.984 0.612 1.230 1.618 1.319 1.293 0.963 1.247 0.919 0.970 0.734 0.970 0.974 1.071 1.247 0.835 0.790 0.918 0.687 0.820 1.113 0.835 0.906 1.141 0.866 1.247 0.671 1.065 1.050 1.153 0.843 1.005 Tokens 1.129 0.616 1.021 0.875 1.095 1.294 1.232 1.206 1.058 0.705 1.227 1.508 1.256 1.320 1.039 1.361 0.926 0.917 0.906 0.920 0.956 1.087 1.274 0.876 0.756 0.805 0.747 0.789 0.986 0.838 0.884 1.021 0.645 1.205 0.723 0.892 0.979 1.108 0.848 0.928 Lines 0.983 0.731 1.029 1.025 1.083 1.325 1.250 1.251 1.085 0.555 1.051 1.360 1.228 1.070 0.920 1.343 0.917 0.865 0.788 1.000 0.906 1.000 1.279 0.909 0.878 0.905 0.731 0.810 1.136 0.843 0.936 1.166 0.966 1.202 0.743 0.925 1.000 1.076 0.750 0.978 BC 1.111 0.591 1.161 0.823 1.080 1.216 1.333 1.000 1.039 0.471 1.037 1.318 0.968 1.113 0.857 1.222 0.720 0.730 0.656 0.667 0.818 0.881 1.414 1.091 1.041 1.065 0.889 1.054 1.406 1.182 1.143 1.114 0.852 1.102 0.871 0.889 1.200 0.938 1.000 0.996 WBC 0.986 0.553 1.112 0.638 1.100 1.036 1.077 0.750 0.907 0.304 0.793 1.019 0.672 0.989 0.495 0.929 0.600 0.491 0.344 0.462 0.563 0.638 1.443 1.427 1.144 1.372 1.000 1.473 1.328 1.688 1.359 1.253 1.221 1.361 1.216 1.071 1.300 1.328 1.462 1.276 D-Ident 0.985 0.759 0.690 0.763 0.842 1.066 1.036 1.099 0.905 0.776 0.964 1.000 1.200 0.895 0.695 0.879 0.737 0.789 0.600 0.709 0.761 0.834 1.133 1.241 1.074 1.342 0.776 1.145 0.943 1.141 1.099 1.091 1.051 1.232 1.110 1.345 1.421 1.457 1.255 1.245 D-RW 0.783 0.522 0.638 0.545 0.774 0.659 0.771 0.600 0.662 1.085 1.109 1.239 0.957 1.227 0.840 1.263 0.774 0.878 0.786 0.943 0.900 1.000 1.149 1.239 1.200 1.227 0.947 1.463 1.429 1.500 1.269 0.766 1.109 0.960 1.404 0.789 1.452 0.786 1.286 1.069 Average

0.949

DALE KRUSE WEISS KRUSE WEISS DALE DALE KRUSE WEISS DALE KRUSE WEISS

BST BST BST LL LL LL QUEUE QUEUE QUEUE STACK STACK STACK

0.930

DALE WEISS DALE WEISS DALE WEISS DALE WEISS

BST BST LL LL QUEUE QUEUE STACK STACK

1.085

DALE KRUSE DALE KRUSE DALE KRUSE DALE KRUSE

BST BST LL LL QUEUE QUEUE STACK STACK

1.071

The average for each metric over each language is summarized in the graph shown below:

0-7803-8552-7/04/$20.00 ? 2004 IEEE October 20 – 23, 2004, Savannah, GA 34th ASEE/IEEE Frontiers in Education Conference S3H-13

Session S3H

1.600 1.400 1.200 1.000 0.800 0.600 0.400 0.200 0.000 Chars Tokens Lines BC WBC D-Ident D-RW C C++ Java Pascal

FIGURE VI COMPARING COMPLEXITY METRICS

CONCLUSIONS The results were surprising. Even though C++ received the lowest overall score, I believe from experience that of the four languages surveyed, C++ contains the most gratuitous complexity. This indicates that there are factors at work influencing syntactic complexity other than those measured. There are, however, some interesting observations. The graph in Figure VI shows that the Java implementations use fewer characters, tokens and lines of source code than the other three languages; however, there is a cost. Java clearly uses more blocks, nested blocks, and reserved words to achieve this goal. Both C and C++ required slightly more tokens and lines of source code than Java and Pascal, but had significantly lower weighted block counts than either Java or Pascal. Consider the C++ linked list node code sample from Figure I. The weighted block count for the C++ node is three; however, the extra weight is made up for by the fact that the node contains initializations for the default values of data members. Another interesting statistic is that the block count for Pascal is relatively low, but the weighted block count is quite high. This can be explained by the fact that Pascal allows for nested procedures and functions, while C and C++ do not. It is not surprising that C had the fewest number of different reserved words, since there are significantly fewer

reserved words in C than in C++ or Java. What is a surprise is the large number of different reserved words needed in the Pascal implementations, since Pascal also has significantly fewer reserved words than C++ or Java. C++ requires the highest number of tokens, yet the second lowest number of different reserved words. In Figure VI, C and C++ were tightly coupled, i.e. their graphs are closely related, which might be expected. However, the graphs of Java and Pascal are also tightly coupled. FUTURE WORK The main problem encountered in this survey lies in the definition of syntactic complexity. Future work will concentrate on the factors influencing syntactic complexity allowing for a better definition. These factors are probably best determined through research on humans. REFERENCES
[1] [2] [3] [4] [5] [6] Alessi, S., M., Trollip, S., R., Computer-based Instruction, 1st edition, 1991. Dale N., B., C++ Plus Data Structures, 3rd edition , 2003. Dale N., B., Joyce, D. T., Weems, Chip Object Oriented Data Structures Using Java, 1st edition, 2002. Dale N., B., Joyce Pascal Plus Data Structures, 2nd edition , 1988. Halstead, M., H. Elements of Software Science, Operating, and Programming Systems Series, Volume 7., 1977. Kruse, R., H., Data Structures and Program Design, 2nd edition, 1987.

0-7803-8552-7/04/$20.00 ? 2004 IEEE October 20 – 23, 2004, Savannah, GA 34th ASEE/IEEE Frontiers in Education Conference S3H-14

Session S3H
[7] [8] [9] Kruse, R., H., Tondo, C., L., Leung, B., Data Structures and Program Design in C, 2nd edition, 1997. Kruse, R., H., Data Structures and Program Design in C++, 1st edition, 1998. McCabe, T., J., Complexity Measure, IEEE Transctions on Software Engineering,, pp 308-320, December 1976. [11] Weiss, M., A. Data Structures and Algorithm Analysis in C++, 2nd edition, 1999. [12] Weiss, M., A. Data Structures and Algorithm Analysis in Java, 2nd edition, 2002. [13] ftp://ftp.prenhall.com/pub/esm/computer_science.s-041/kruse [14] http://computerscience.jbpub.com/cs_resources.cfm [15] http://www.cs.fiu.edu/~weiss/dsaajava/code/

[10] Weiss, M., A. Data Structures and Algorithm Analysis, 2nd edition, 1994.

0-7803-8552-7/04/$20.00 ? 2004 IEEE October 20 – 23, 2004, Savannah, GA 34th ASEE/IEEE Frontiers in Education Conference S3H-15


相关文章:
The Evolution of Data Structures_图文.pdf
The Evolution of Data Structures - Abstract- For over 20 years, the data structures course has be...
Structure and Evolution of International Migration Networks_....pdf
Structure and Evolution of International Migration Networks_电子/电路_工程科技_...theoreticalmethodsdataas based on a basicconceptalongwith a globalmigrationas ...
lecture 1'-The Evolution of Dataabase Systems(Chapter 1)_图文....ppt
lecture 1'-The Evolution of Dataabase Systems(Chapter 1)_IT/计算机_专业...for the data) is limited to the creation of directory structures for files...
Evolving data structures with genetic programming.pdf
Evolving data structures with genetic programming_专业资料。Genetic programming ... is introduced to GP in order to facilitate the evolution of primitives ...
Evolving Data Structures with Genetic Programming.pdf
Evolving Data Structures with Genetic Programming_英语学习_外语学习_教育专区。... is introduced to GP in order to facilitate the evolution of primitives ...
Evolution and restoration of structures and functions of the ....pdf
Evolution and restoration of structures and functions of the human central nervous systemA review_电子/电路_工程科技_专业资料。Translational Neuroscience and...
...and Evolution on Large Computer Data Structures.pdf
Self-Organization and Evolution on Large Computer Data Structures_专业资料。We study the long time evolution of a large data structure while inserting new ...
Structure and Evolution of the World Trade Network.pdf
For instance, in ?g.1c we show the evolution of the number of countries N(t) during such time interval. For the 1995 data, the number of ...
Analysis on the Evolution of Agricultural Structure about Pan....pdf
Analysis on the Evolution of Agricultural Structure about Pan-Yangtze River Delta_经济/市场_经管营销_专业资料。Arutrlcne&Tcnlg21gilaSiccu eehooy,00,1()...
Structure of a product database supporting model evolution_....pdf
Structure of a product database supporting model evolution_专业资料。ABSTRACT:...EDM-2 incorporates distinct structures for building up relations between ...
Evolution of Self-Assembled Structures of_图文.pdf
Evolution of Self-Assembled Structures of_医药卫生_专业资料。COMMUNICATION DOI: 10.1002/adma.200702786 Evolution of Self-Assembled Structures of Polymer-Termin...
Evolution of Organization Structure.doc
Evolution of Organization Structure Understanding the historical context from which some of today's organizational structures have developed helps to explain why...
...Structured Program Evolution Evolution of Loop Structures_....pdf
Evolution: Evolution of Loop Structures 181 Structure of GRAPE Graph-structured programs are composed of an arbitrary directed graph of nodes and a data ...
外文翻译Structure and morphology evolution TiAlSi(李政)_....doc
外文翻译Structure and morphology evolution T
...ofLargeScaleStructure{Garching,August1998 THEEVOLUTIONOF....pdf
ProceedingsEvolutionofLargeScaleStructure{Garching,August1998 THEEVOLUTIONOFTHE...A full analysis of these data will enable us to determine how the ...
Evolution of Relational Database to Object-Relational Data....pdf
Evolution of Relational Database to Object-Relational Database in Abstract ...The port for richer object structures and rules and still be Informal ...
Database schema evolution using EVER diagrams.pdf
Database schema evolution using EVER diagrams_专业资料。We present an ...Concept D, a graphical language that supports multilevel concept structures ...
Structure Evolution and Ornament Elimination_图文.pdf
Take the Home Insurance Building for example, it represented a decisive step in the evolution of iron and steel framing, and became one of the most ...
...for Inferring the Evolution of Eukaryotic Gene Structure_....ppt
Data Components The Model The Algorithm Results Homogeneous Evolution 234 295 187 genes genes genes Results Heterogeneous Evolution Summary Gene ...
Experimental study on evolution of bed structures of natural ....pdf
Experimental study on evolution of bed structures of natural mountain rivers_天文/地理_自然科学_专业资料。Waececn nierg21.()1223trineadEgnen,0 42: 0 ...