950 likes | 1.29k Views
DATA STRUCTURE. Instructor: Dai Min Office: XNA602 Fall 2006. CHAPTER 2 List, Stacks and Queues. Abstract Data Types (ADTs) Linear List Array-based List Linked List Stacks and Applications Queues and Applications. 2.1 Abstract Data Type.
E N D
DATA STRUCTURE Instructor: Dai Min Office: XNA602 Fall 2006
CHAPTER 2 List, Stacks and Queues • Abstract Data Types (ADTs) • Linear List • Array-based List • Linked List • Stacks and Applications • Queues and Applications
2.1 Abstract Data Type • Data TypeA data type is a collection of objects and a set of operations that act on those objects. • e.g. in C: int [-32768, +32767] • Legal operations on integers: + - * / ... • Abstract Data TypeAn Abstract Data Type (ADT) is a data type together with the operations, whose properties are specified independently of any particular implementation.
Example:Abstract data type Natural_Number ADTNaturalNumber { objects: an ordered subrange of the integers starting at zero and ending at the maximum integer (INT_MAX) on the computer functions: for all x, y Nat_Number; TRUE, FALSE Boolean and where +, -, <, and == are the usual integer operations.Int Zero ( ) ::= 0Boolean Is_Zero(x) ::= if (x) returnFALSEelse returnTRUEint Add(x, y) ::= if ((x+y) <= INT_MAX) return x+y else returnINT_MAXBoolean Equal(x,y) ::= if (x== y) returnTRUEelse returnFALSEint Successor(x) ::= if (x == INT_MAX) return xelse return x+1int Subtract(x,y) ::= if (x<y) return 0else return x-y} NaturalNumber
Logical vs. Physical Form Data items have both a logical and a physical form. • Logical form: definition of the data item within an ADT. • Ex: Integers in mathematical sense: +, - • Physical form: implementation of the data item within a data structure. • Ex: 16/32 bit integers, overflow.
2.2 Linear List 1)Definition:A list is a finite sequence of data elements from the same data type. Notation:L = (a1, a2, …, an) name • a1 is the list head,an is the last element • n is the length of the list. If n=0, we call the list an empty list. • ai-1 is the directlypredecessor ofai • ai+1 is the directlysuccessor ofai
A list is a data structure where data is represented linearly. • For a List (not empty) • There is one and only“head” element • There is one and only“last” element • Except the list head, every element has one and only one directly predecessor. • Except the last element, every element has one and only one directly successor.
2)ADT of List ADT List { Objects: D={ ai | ai ∈ElemSet, i=1,2,...,n, n≥0 } Function: R1={ <ai-1 ,ai > | ai-1 ,ai∈D, i=2,...,n } InitList( &L ) DestroyList( &L ) ListEmpty( L ) ListLength( L ) GetElem( L, i, &e ) …… } ADT List
2.2.1 Simple Array Implementation of Lists A list can be implemented using arrays on a machine. 1)data elementsare stored in a contiguousmanner. If an element is represented by d bytes, then the n-length list is : the position of the i’th element: Loc(ai)=Loc(ai-1)+d Loc(ai)=Loc(a1)+(i-1)*d 1≤i≤n ——Random Access
2) Array-based List # define List_Init_Size 100 // the initial size of list # define ListIncrement 10 // Incremental size typedef xxx Elemtype // the data type of each element typedef struct { Elemtype elem[List_Init_Size]; // using an array int length; //the length of list int listsize; //maximum size of list } SqList;
SqList L ; L. elem[0] // the head element a1 L. elem[L.length-1] // the last element an L.length // the length of the list
3)Operations on Array-based List ① Initialization (construct an empty list)SqList init_SqList( ) { SqList L; L.elem = (ElemType *) malloc (List_Init_Size * sizeof (ElemType) ); if ( ! L.elem) exit(overflow); //Out of space L.length = 0; L.listsize = List_Init_Size; // initial size return L; }
② Retrieve the i’th element Where is the i’th element ElemType GetItem(Sqlist L, int i) { ElemType e; e = L.elem[i-1]; return e; }
③ Insert a new element at the position i SqList Insert_SqList(SqList L,int i,Elemtype x) { if ((i<1) || ( i>L.length+1)) return ERROE; //whether i is legal? if (L.length >= L.listsize) // whether the list is full? { newbase = (ElemType *) realloc(L.elem, L.listsize+ListIncrement)*sizeof(ElemType)); if ( ! newbase) exit(overflow); // Out of space L.elem=newbase; L.listsize + =ListIncrement; } // allocate new storage space for (m =L.length-1; m >= i-1; --m) L.elem[m+1] = L.elem[m]; L.elem[i-1] = x; L.length ++; Return L; }
Algorithm Analysis: Asymptotic Time Complexity: • Best Case : when i = n+1,T(n)=O(1) • Worst Case:when i=1, T(n)=O(n) • Average Case : T(n)=O(n)
SqList Delete_SqList(SqList L, int i,Elemtype e) { if ((i<1) || (i>L.length)) // whether i is legal? return ERROE; e = L.elem[i-1]; //retrieve the i’th element for ( i; i<=L.length-1; ++i ) L.elem[i-1] = L.elem[ i ]; // elements move backward --L.length; // length-1 Return L; }
Algorithm Analysis: • Best Case : when i = n,T(n)=O(1) • Worst Case:when i=1, T(n)=O(n) • Average Case : T(n)=O(n)
⑤ Find the first occurrence of X x = 48 x = 50
int LocateElem_Sq(SqList L,Elemtype x) { int i = 1; while( I <= L.length && L.elem[i -1] != x) i ++; if (i >L.length) return -1; else return i; /*Return the position of x */ }
Summary of array-based list • Array implementation of list • successive element are adjacent in memory • disadvantage • Element movements during insertion and deletion • Waste considerable space in storing the list of varying size • possible solution • linked list • linked lists are dynamically allocated
2.2.2 Linked List • Linked list • Successive elements are not necessarily adjacent in memory. Instead, data is stored at random locations and the current data location provides the information regarding the location of the next data. • Elements connected by pointer links. Using pointers to point to the next element. • Use a linked list instead of an array when • You have an unpredictable number of data elements • Insertion and deletion are frequent
Types of linked list: • Singly linked list • Begins with a pointer to the first node • Terminates with a null pointer • Only traversed in one direction • Circular, singly linked list • Pointer in the last node points back to the first node • Doubly linked list • Each node has a forward pointer and a backward pointer • Allows traversals both forwards and backwards • Circular, doubly linked list • Forward pointer of the last node points to the first node and backward pointer of the first node points to the last node
1) Singly Linked List • Each structure contains the element and a pointer to a structure containing its successor, called a node. • Link pointer in the last node is set to null to mark the list’s end. • Accessed via a pointer to the first node of the list. e.g. (a1,a2,a3 ,a4)
2) Linked List with a header • In practice, we keep a sentinel node, referred as a header or dummy node. • The header is in position 0. An un-empty linked list Empty list with header
3) Linked List Implementation Typedef struct Lnode{ ElemType data; // Data Field Struct Lnode *next; // Pointer (Link) Field }Lnode,*LinkList; LinkList L; // Lnode *L; The location of the first element: L->next Value for the first element:L->next->data
4)Operations on linked list ① Insertion into a Listed List e.g. Insert a new node before the i’th node Before insert (After insert)
Linklist ListInsert (LinkList L, int i, Elemtype x ) • { //在带头结点单链表第 i 个结点前插入新元素x • p=L; j=0; • while ( p != NULL && j<i -1 ) • { p = p→next; j++;} //找第 i-1个结点 • if ( p == NULL || j>i-1) return Error; • newnode= (LinkList ) malloc(sizeof(Lnode)); • //创建新结点,其数据为x • newnode→data=x; • newnode→next = p→next; • p→next = newnode; return (L); • } • T(n) = O(n)
② Create a linked List • Analyzing 1) Create an empty linked list 2) Insert n nodes after the header
Linklist CreateList_L ( int n ) { LinkList L; L= (LinkList) malloc(sizeof(Lnode)); L->next=NULL;//建立一个空表 for( i=n; i>0 ; --i ) { p= (LinkList) malloc(sizeof(Lnode)); //为新结点分配存储单元 scanf(&P->data); //读入要插入元素值 p->next= L->next; L->next=p; //修改链接关系 } return(L); } • T(n) =O(n)
③ Deletion of an Element from a List Delete the i’thelement from the list
Linklist ListDelete (LinkList L, inti, ElemType &e ) • { //在单链表中删除第 i 个结点 • p =L; j = 0; • while ( p →next&& j<i-1 ) • { p = p→next; j++; } //找第 i-1 个结点 • if ( !(p →next)|| j>i-1) return Error; • q=p→next; p→next=q→next; //重新链接 • e= q→data; • free(q);//释放q结点 • return(L); • } • T(n) = O(n)
④Find the first occurrence of X LinkList Locate_LinkList( LinkList L, ElemType x) /*在单链表L中查找值为x的结点,找到后返回其指针,否则返回空*/ { LinkList p; p=L->next; while ( p!=NULL && p->data != x) p=p->next; // 向后查找 return p; } • T(n) =O(n)
⑤ Count the Elements of a linked List int Listlength_L ( LinkList L) { i=0; p=L; while ( p->next !=NULL) { i++ ; p= p->next; } return(i); } • T(n) =O(n)
Summary of singly linked list • Subsequent nodes are accessed via the link-pointer member of the current node. • When insertion or deletion, locating the predecessor node. • A Linked list is accessed via a pointer to the first node of the list. • Linked list is sequential access structure.
2.2.3 Circular, singly linked list 1)A singly linked list that the pointer in the last node points back to the first node.
A circular, singly linked list with trail pointer The last element :*rear The first element:rear->next->next • In acircularly singly linked list, every elements can be accessed from an node.
2) Circularly singly linked list implementation Typedef struct Lnode { ElemType data; // Data Field Struct Lnode *next; // Pointer (Link) Field } Lnode,*LinkList; (Same as singly linked list) 3)Operation on circularly singly linked list: • Create • Length • Locate: • Insertion: • Deletion: Where is the end of the circular linked list Same as singly linked list
E.g.Count the Elements of a circular linked List: int Listlength_CL (LinkList L) { j=0; p=L->next; while (p!= L) { j++; p=p->next;} return ( j ); }
2.2.4 Doubly linked list 1) Each node contains a data field and two pointer fields, a forward pointer and a backward pointer. Allows traversals both forwards and backwards. • Circular, doubly linked list
2) Doubly linked list implementation Typedef struct DuLnode{ ElemType data; // Data Field Struct DuLnode * prior, *next; // Pointer Field }DuLnode,*DuLinkList; p->next->prior = p->prior->next
3) Operations for doubly Linked List ① Insertion into a doubly Listed List DuLinkList ListInsert_Dul(DuLinklist L,int i, Elemtype x) { if ( !(p=GetElemP_Dul(L,i))) return ERROR; if (! (s=(DuLinklist)malloc(sizeof(DuLnode)))) return ERROR; s->data=x; s->prior=p->prior; p->prior->next=s; s->next=p; p->prior=s; return (L); }
② Delete an Element from a doubly List DuLinkList ListDelete_Dul(DuLinklist L,int i, Elemtype &e) { if ( !( p =GetElemP_Dul(L,i))) return ERROR; e=p->data; p->prior->next = p->next; p->next->prior = p->prior; free (p); return (L); }
2.2.5 Example: Polynomials • Polynomials • Pn(x) (n+1 items) • Coefficient:a0, a1, a2, …, an • Exponent:0, 1, 2, …, n
2)Representation • Array-based implementation • Disadvantage: for sparse polynomials e.g. P101(x) = 3 + 5x50 - 14x101
Linked list implementation • An item represent by a node typedef struct poly_node { int coef; int expn; struct poly_node *next; }; • e.g.AH = 1 - 10x6 + 2x8 +7x14
3)Adding Polynomials AH = 1 - 10x6 + 2x8 +7x14 BH = - x4 + 10x6 - 3x10 + 8x14 +4x18
Summary of Linked list • Advantanges of linked list: • store items "sequentially" without restrictions on location • insert new item without shifting • delete existing item without shifting • size can expand/contract throughout use • Disadvantages • overhead of links: used only internally, pure overhead • no longer have direct access to each element of the list. O(1) access becomes O(n) access since we must go through first element, and then second, and then third, etc.
Comparison of Implementation • Array-Based List: • Insertion and deletion are O(n). • Direct access are O(1). • Array must be allocated in advance. • No overhead if all array positions are full. • Linked List: • Insertion and deletion are O(1). • Direct access are O(n). • Space grows with number of elements. • Every element requires overhead.