the second linear structure of the data structure
2.1 Linear table and its realization
2.1.1 Primer: Polynomial representation
Example: one-element polynomial and its operationOne-dimensional polynomial: f (x) = a0 + a1x + a2x^2 + ... + a (n-1) x ^ (n-1) + an x^n main operation: polynomial addition, subtraction, multiplication and so on how to express the polynomial. Key data for polynomials: polynomial number n, various coefficients ai and exponent i
Method 1: Sequential storage structure directly representsVarious components of the array corresponding polynomial: A[i]: X^i factor AI For example: f (x) = 4*x^5-3*x^2 +1 as a[0] = 1,a[1] = 0,a[2] = -3,a[3] = 0,a[4] = 0, a[5] = 42 polynomial add : two array corresponding to the component addition problem: how to represent the polynomial x+3*x^2000? At least 2001 of the size of the array, resulting in a huge space waste.
Method 2: Sequential storage structure represents non 0 itemsEach of the 0 items involved two information: coefficient ai, exponent I, you can think of polynomial as a set of (Ai,i) two tuples is represented by an array of structures: The array component is a structure composed of a coefficient ai, an exponent I, corresponding to a non 0 term. Orderly storage by exponential size
Add process: Start from the beginning, compare the index of the current corresponding item of two polynomials, the output is large, the exponent is the same, the corresponding coefficient is added and then output.
Method 3: Chain-list structure stores non-0 itemsEach node in a list stores a non 0 item in a polynomial, including the coefficients and exponent two data fields and a pointer field.
typedef struct POLYNODE* polynomial;
struct polynode{
int coef; coefficient
int expon; index
polynomial link;
The logical process and Method 2 of the addition operation are the same.
2.2.1 Linear table and sequential storageWhat is the implication of the linear table polynomial representation problem: 1. The same problem can have different representation (storage) methods; 2. There is a common problem: the organization and management of ordered linear sequences (Linear list): A data structure consisting of an ordered sequence of data elements of the same type. The number of elements in a table is called the length of a linear table; a linear table is called an empty table when it has no elements; The table's starting position is the header, and the end of the table is called the footer.
sequential storage implementation of linear tableStoring the elements of a linear table using the sequential storage space sequence of an array
typedef struct LNODE* List;
struct lnode{
ElementType data[maxsize]; The storage element's array
int last; The position of the last element
};
struct Lnode L;
List Ptrl;
Access the element labeled I: L.data[i] or ptrl->data[i] The length of the linear table: L.last + 1 or Ptrl->last + 1 main operations of the implementation 1. Initialize (set up empty sequential table)
List Makeempty ()
{
list Ptrl;
Ptrl = (List) malloc (sizeof (struct lnode));
Ptrl->last =-1;
return Ptrl;
2. Find
int find (ElementType x,list Ptrl)
{
int i = 0;
while (i <= ptrl->last && ptrl->data[i]!= x)
i++;
if (i > Ptrl->last)
return-1; If not found, return-1
else returns
i; The storage location is returned when found
}
The average number of successful lookups is (n+1)/2, and an average performance of O (n) is achieved
2.1.3 Sequential storage inserts and deletes3. Insert a new element with a value of x in the position (1<=i<=n+1)
void Insert (ElementType x,int i,list Ptrl)
{
int J;
if (ptrl->last = = MAXSIZE-1) //Table space is full, cannot insert
{
printf ("Table full \ \");
return;
}
if (I < 1 | | | i > ptrl->last + 2) //Check the legality of the insertion position
{
printf ("Invalid location \ \ \ n");
return;
}
for (j = ptrl->last;j >= i-1; j--)
ptrl->data[j+1] = ptrl->data[j]; Move Ai~an backwards
ptrl->data[j] = x; Inserts a new element into the
ptrl->last++; Last still points to final element return
;
Average moving number is N/2, average time performance is O (n)
4. Delete (delete the elements in the table I (1<=i<=n) position)
void Delete (int i,list Ptrl)
{
int J;
if (I < 1 | | | i > ptrl->last + 1) //Check the legality of empty table and deletion location
{
printf ("No%d elements exist", I);
return;
}
for (j = i;j < ptrl->last;j++)
ptrl->data[j-1] = ptrl->data[j]; Move the Ai+1~an order forward
ptrl->last--; Last still points to the final element return
;
Average moving number (n-1)/2, average time performance is O (n)
2.1.4 Chain Storage and lookup linear table chain store implementation does not require that logically adjacent two elements are physically adjacent; inserting, deleting logical relationships between data elements by "chaining" you don't need to move data elements, just modify the chain
typedef struct LNODE* List;
struct lnode{
ElementType Data;
List Next;
};
struct Lnode L;
List Ptrl;
Implementation of the main operation 1. Find the table length
int Length (list Ptrl)
{
list p = Ptrl; P points to the first node of the table
int j = 0;
while (p) {
p = p->next;
j + +; The current P points to the J node} return
J;
}
Time performance is O (n) 2. Find (1) by ordinal find: findkth
List findkth (int k,list Ptrl)
{
list p = Ptrl;
int i = 1;
while (P!= NULL && i < K)
{
p = p->next;
i++;
}
if (i = = K) return
p; Find the k, return pointer
else returns
NULL; otherwise return null
(2) Search by value: Find
List find (ElementType x,list Ptrl)
{
list p = Ptrl;
while (P!= NULL && p->data!= x)
p = p->next;
return p;
}
Average Time performance O (n)
Another implementation of the FINDKTH function in 2.1-chained storage is discussed.
If you make a modification to the function implementation of FINDKTH in chained storage (as follows), change the last if statement of the function to determine if p is null, that is:
if (p==null) return NULL; else return p;
Or the direct simplification is: return p;
is the program still correct for such a modification? Why.
List *findkth ( int K, List *PtrL ) { list *p = PtrL; int i = 1; while (p !=null && i < k ) { p = p- >Next; i++; &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP} if (I == K) return p; /* find k, return pointer/ else return null; /* otherwise return null */}
A: If k<1, then return Ptrl instead of NULL, so incorrect. 2.1.5-Chained storage inserts and deletes 3. Inserting (inserting a new node with a value of x after the i-1 (1<=i<=n+1) node) (1) Constructing a new node, using S point (2) to find the first i-1 node of the linked list, and using p to point to (3) Then modify the pointer, insert the node (p after the insertion of the new node is s).
List Insert (ElementType x,int i,list Ptrl)
{
list p,s;
if (i = = 1) //new node is inserted in the table header
{
s = (list) malloc (sizeof (struct lnode)); Application, filling node
s->data = x;
S->next = Ptrl;
return s;
}
p = findkth (I-1,ptrl); Find the I-1 node
if (p = = NULL) //i-1 does not exist, cannot insert
{
printf ("Parameter I Error");
return NULL;
}
Else
{
s = (List) malloc (sizeof (struct lnode)); Application, filling node
s->data = x;
S->next = p->next; The new node is inserted at the back of the first i-1 node
p->next = s;
return Ptrl;
}
Average lookup times n/2 4. Delete (delete the node in the position of the first (1<=i<=n) of the list) (1) First find the I-1 node of the list, use P to point (2) again to point to the node to be deleted (the next node of P) (3) and then modify the pointer to delete s-point node (4) Releasing the space of the point of the node of S
List Delete (int i,list Ptrl)
{
list p,s;
if (i = = 1) //To delete is the first node of the table
{
s = Ptrl; S points to the first node
if (Ptrl!= NULL) //deletes Ptrl from the list
= ptrl->next;
else return
NULL;
Free (s); Release the deleted node return
Ptrl;
}
p = findkth (I-1,ptrl); Find the I-1 node
if (p = = NULL)
{
printf ("%d node does not exist", i-1);
return NULL;
}
else if (P->next = NULL)
{
printf ("%d node does not exist", I);
return NULL;
}
Else
{
s = p->next; s point to the first node
p->next = s->next; Remove free
(s) from the list; Release the deleted node return
Ptrl;
}
Average lookup times N/2
2.1.6 Generalized table and multiple linked list
Generalized Table
The Generalized table (generalized list) is the generalization of the linear table, and for the linear table, n elements are basic single elements, in the generalized table, these elements can be not only cell element but also another generalized table.
typedef struct GNODE* glist;
struct gnode{
int Tag; The flag field, 0 indicates that the node is a cell element, and 1 indicates that the node is a generalized table
union{ //child table pointer domain sublist and a single element data domain, that is, the shared storage space
ElementType data;
Glist sublist;
} uregion;
Glist Next; Point to subsequent nodes
multiple linked lists: nodes in a linked list may belong to multiple chains at the same time.The pointer field of a node in a multilink list can be multiple, as in the previous example, the two pointer fields of next and sublist are included, but a list containing two pointer fields is not necessarily a multiple linked list, such as a doubly linked list is not a multiple list. Multi-linked lists have a wide range of uses: basically, such as trees, graphs, such as relatively complex data structures can be used to implement a multiple-linked table storage. Example: A matrix can be represented in a two-dimensional array, but a two-dimensional array represents two defects: one is that the size of the array needs to be determined in advance. The second is for "sparse array" (0 many, not 0 items very few), will cause a lot of storage space waste analysis: A typical multiple linked list--cross linked list to store sparse matrices Only data fields that have a matrix of 0 element nodes are stored: row coordinates row, column coordinate col, value value each node passes through two pointer fields, and the peers and columns are strung together. The right column pointer (or called the pointing down pointer) down
Use an identifier tag to differentiate between the head node and the non 0 element node: The head node's flag value is headed, and the value of the matrix non-0 element node is term
2.2 Stack
2.2.1 What is a stackThe stack is a linear structure and is also a special linear table. function calls, recursion, expression evaluation are used on the stack. Example: How does a computer evaluate an expression. Arithmetic expressions are made up of two types of objects: operands, such as 2, 3, 4, operations symbols, such as + 、-、 *, and/, different operator symbols are not the same precedence. Infix expression: The operation symbol is located between the two-op count. Suffix expression: The operation symbol is located after two operands. Suffix expression evaluation strategy: scan from left to right, processing operands and operation symbols on the count of operations. Remember, when you encounter an operational symbol, you deal with the last two op-math revelations: You need a storage method that can store the operands sequentially and then output in reverse order when needed.
abstract data type description of the stackStack: a linear table with certain operational constraints inserts, deletes, and inserts data at one end (top of stack): on stack (Push) Delete data: Out of Stack (POP), after first (LIFO)
sequential storage Implementation of the 2.2.2 stackThe sequential storage structure of stacks is usually composed of a one-dimensional array and a variable that records the position of the top element of the stack.
#define MAXSIZE < Store the maximum number of data elements >
typedef struct snode* Stack;
struct snode{
ElementType data[maxsize];
int top;
1. Into the stack
void push (Stack ptrs,elementtype item)
{
if (ptrs->top = = MAXSIZE-1)
{
printf ("Stack full");
return;
}
else
{
ptrs->data[++ (ptrs->top)] = Item;
return;
}
2. Out Stack
ElementType pop (Stack ptrs)
{
if (ptrs->top = 1)
{
printf ("heap null");
return ERROR; Error is a special value for ElementType, marking errors
}
else {return
(ptrs->data[(Ptrs->top)--]);
Example: Using an array to implement two stacks, requiring maximum use of the array space, so that the array as long as there is space, the stack operation can be successful. Analysis: A more clever way is to make the two stacks from the end of the array to the middle of the growth, when the top two stacks of stacks of pointers to meet, said two stacks are full.
#define MAXSIZE < Storing the maximum number of data elements >
struct dstack{
elementtype data[maxsize];
int Top1; Stack 1 on top of the stack pointer
int Top2; Stack 2 on the top of the stack pointer
}s;
S.TOP1 =-1;
S.TOP2 = MAXSIZE;
1. Into the stack
void push (struct dstack* ptrs,elementtype item,int Tag)
{
if (Ptrs->top2-ptrs->top1 = 1) //Stack full c25/>{
printf ("Stack full");
return;
}
if (Tag = = 1)//to the first stack operation
ptrs->data[++ (PTRS->TOP1)] = Item;
Else<span style= "White-space:pre" > </span>//to the second stack operation
ptrs->data[--(PTRS->TOP2)] = item;
}
2. Out Stack
ElementType POPs (struct dstack* ptrs,int Tag) //tag as a marker for distinguishing two stacks, values 1 and 2
{
if (tag = = 1) //On the first stack operation
{
if (Ptrs->top1 = = 1)//stack 1 empty
{
printf ("Stack 1 Empty");
return NULL;
}
else return
ptrs->data[(PTRS->TOP1)-];
}
else //to the second stack operation
{
if (ptrs->top2 = = MAXSIZE) //Stack 2 empty
{
printf ("Stack 2 Empty");
return NULL;
}
else return
ptrs->data[(PTRS->TOP2) + +];
}
discusses another implementation of 2.2 stack order storage
Another way in which stacks are implemented by arrays is given, which is to pass the array and top variables directly in the function arguments (rather than the structure pointers of both), where the push action function is designed as follows. Is this push function correct? Why. #define MaxSize ElementType S[maxsize]; int top; void Push (ElementType *s, int top, ElementType item) {if (top==maxsize-1) {printf ("stack full"); Return }else {S[++top] = Item; Return A: Incorrect, top is passed by value, the value of the global variable top is not changed when the function ends.
2.2.3 Stack chain store implementation stack chain storage structure is actually a single linked list, called Chain stack. Insert and delete operations can only be done on the stack top of the chain stack. Top is on the head of the list, and the last node cannot be found after the delete operation, if it is placed at the end of the list.
typedef struct SNODE* Stack;
struct snode{
ElementType Data;
Stack Next;
1. Stack initialization (set up empty stack)
Stack Createstack ()
{
//build an empty node of a stack, return pointer
stack S;
S = (Stack) malloc (sizeof (struct snode));
S->next = NULL;
return S;
}
2. Determine if the stack s is empty
int IsEmpty (stack s)
{
//determine if stack s is null, returns an integer 1 for null function, or returns 0 return
(s->next = NULL);
3. Into the stack
void push (ElementType item,stack s)
{
//presses the element item into the stack S stack
tmpcell;
Tmpcell = (Stack) malloc (sizeof (struct snode));
Tmpcell->data = Item;
Tmpcell->next = s->next;
S->next = Tmpcell;
4. Out Stack
ElementType pop (stack s)
{
//delete and return stack s on top element stack
FirstCell;
ElementType Topelem;
if (IsEmpty (S))
{
printf ("stack null");
return NULL;
}
else
{
FirstCell = s->next;
S->next = firstcell->next;
Topelem = firstcell->data;
Free (FirstCell);
return topelem;
}
2.2.4 Stack application: evaluation of ExpressionsReads the various (operators or operands) of the suffix expression from left to right: 1. Operand: into stack; 2. Operator: POPs the appropriate number of operands from the stack, calculates and results into the stack; 3. Finally, the element on top of the stack is the result value of the expression.
infix expression EvaluationBasic policy: Convert infix expressions to suffix expressions, then evaluate infix expression and suffix expression: 1. The relative order of the OP arithmetic is unchanged; 2. The order of the operands changes: you need to store the operation symbol in wait; To compare the current operation symbol with the last operation symbol in the wait How infix expressions are converted to suffix expressions: Read each object of infix expression from beginning to end, and treat different objects in different situations. 1. Operand: direct output; 2. Opening parenthesis: pressing into stack; 3. Closing parenthesis: the operator on top of the stack pops up and outputs until it encounters the opening parenthesis (out of stack, not output) 4. Operator: If precedence is greater than the stack operator, the stack operator is ejected and output if the priority is less than or equal to the stack top operator, Compare the new stack-top operator until the operator is greater than the top of the stack operator, and then press the operator to stack; 5. If the objects are processed, the remaining operators in the stack are exported together.
Other applications of the stack: function invocation and recursive implementation; depth first search; backtracking algorithm ...
2.3 Queues
2.3.1 Queue and sequential storage implementationQueues, like stacks, are also restricted linear tables.
queues: Linear tables with certain operational constraintsInsert and DELETE operations: can only be inserted at one end and deleted at the other end. Data insertion: Into queue (ADDQ) Data deletion: Out queue (DELETEQ) first come first service first out: FIFO
sequential storage implementation of queuesThe sequential storage structure of a queue is usually composed of a one-dimensional array and a variable front that records the position of the queue head element and a variable rear that records the position of the tail element of the queue.
#define MAXSIZE < Storing the maximum number of data elements >
struct qnode{
elementtype data[maxsize];
int front;
int rear;
};
typedef struct QNODE* Queue;
Looping queues