数据结构与算法 期末复习 zstu 浙江理工大学 2023学年第1学期 数据结构与算法
huffman 带权路径长度 WPL: 路径长度 * 点的权值 prim: 在已确定生成树的相邻边找最小的 kruskal: 边按权值升序,依次选中,不能形成环 dijkstra: 每轮确定一个距离源点最短的点 floyd: 对于每一对顶点,尝试通过另一个顶点查找更短路径 Hash 失败查找长度:表内所有项都要计算(?) 直到找到空的次数 程序填空注意 T==NULL 的情况 树->二叉树:兄弟相连;取左孩子
第 1 章 绪论 1.2 算法和算法评价 1.2.2 性能指标
第 2 章 线性表 2.2 顺序表示 内容略
题目 假设顺序表的长度为 n,
若在位序 1 处删除元素,则需要移动 n-1 个元素;
若在位序 n 处删除元素,则需要移动 0 个元素;
若在位序 i (1≤i≤n) 处删除元素,则需要移动 n-i 个元素。
假设各位序删除元素的概率相同,则平均需要移动 (n-1)/2 个元素。
假设顺序表的长度为 n,
若在位序 1 处插入元素,则需要移动 n 个元素;
若在位序 n+1 处插入元素,则需要移动 0 个元素;
若在位序 i (1≤i≤n+1) 处插入元素,则需要移动 n-i+1 个元素。
假设各位序插入元素的概率相同,则平均需要移动 n/2 个元素。
2.3 链式表示 2.3.1 定义 typedef struct LNode { int data; struct LNode * next ; }LNode, *LinkList;
2.3.2 单链表操作 头插法
LinkList headInsert (Linklist &L) { LNode *s; int x; L = (LinkList)malloc (sizeof (LNode)); L -> next = NULL ; while (scanf ("%d" , &x)){ s = (LNode*)malloc (sizeof (LNode)); s -> data = x; s -> next = L -> next, L -> next = s; } return L; }
尾插法
LinkList tailInsert (LinkList &L) { int x; L = (LinkList)malloc (sizeof (LNode)); LNode *newNode, *tail = L; L -> next = NULL ; while (scanf ("%d" , &x)){ newNode = (LNode*)malloc (sizeof (LNode)); newNode -> data = x; tail -> next = newNode, tail = newNode; } tail -> next = NULL ; return L; }
按序号查找
LNode* getElem (LinkList L, int k) { if (k < 1 ) return NULL ; LNode* p = L -> next; for (int i = 1 ; i <= k; i++){ if (p != NULL ) p = p -> next; } retun p; }
按值查找 LNode* findElem (LinkList L, int x) { LNode* p = L -> next; while (p != NULL && p -> data != x) p = p -> next; return p; }
插入结点
删除结点
题目
Node* reverseLinkedListMethod1 (Node* head) { Node* prev = NULL ; Node* current = head; Node* next; while (current != NULL ) { next = current->next; current->next = prev; prev = current, current = next; } return prev; } Node* reverseLinkedListMethod2 (Node* head) { if (head == NULL || head->next == NULL ) return head; Node* newHead = reverseLinkedListMethod2(head->next); head->next->next = head; head->next = NULL ; return newHead; }
第 3 章 栈、队列和数组 3.1 栈
#include <stdio.h> #include <stdlib.h> #define MAX_SIZE 100 typedef struct { int items[MAX_SIZE]; int top; } Stack; void initializeStack (Stack *s) { s->top = -1 ; } int isEmpty (Stack *s) { return s->top == -1 ; } int isFull (Stack *s) { return s->top == MAX_SIZE - 1 ; } void push (Stack *s, int item) { if (isFull(s)) { printf ("栈已满,无法添加元素\n" ); return ; } s->items[++s->top] = item; } int pop (Stack *s) { if (isEmpty(s)) { printf ("栈为空,无法弹出元素\n" ); return -1 ; } return s->items[s->top--]; } int main () { Stack s; initializeStack(&s); push(&s, 10 ); push(&s, 20 ); push(&s, 30 ); printf ("弹出的元素:%d\n" , pop(&s)); printf ("弹出的元素:%d\n" , pop(&s)); return 0 ; }
3.2 队列
#include <stdio.h> #include <stdlib.h> #define MAX_SIZE 100 typedef struct { int items[MAX_SIZE]; int front, rear; } Queue; void initializeQueue (Queue *q) { q->front = -1 ; q->rear = -1 ; } int isEmpty (Queue *q) { return q->rear == -1 ; } int isFull (Queue *q) { return q->rear == MAX_SIZE - 1 ; } void enqueue (Queue *q, int item) { if (isFull(q)) { printf ("队列已满,无法添加元素\n" ); return ; } if (isEmpty(q)) { q->front = 0 ; } q->rear++; q->items[q->rear] = item; } int dequeue (Queue *q) { if (isEmpty(q)) { printf ("队列为空,无法弹出元素\n" ); return -1 ; } int item = q->items[q->front]; q->front++; if (q->front > q->rear) { initializeQueue(q); } return item; } int main () { Queue q; initializeQueue(&q); enqueue(&q, 10 ); enqueue(&q, 20 ); enqueue(&q, 30 ); printf ("出队的元素:%d\n" , dequeue(&q)); printf ("出队的元素:%d\n" , dequeue(&q)); return 0 ; }
3.4 数组和特殊矩阵 3.4.3 特殊矩阵的压缩存储 对称矩阵
三角矩阵
题目
double eval () { char s[100 ]; scanf ("%s" , s); switch (s[0 ]) { case '+' : return eval() + eval(); case '-' : return eval() - eval(); case '*' : return eval() * eval(); case '/' : return eval() / eval(); case '^' : { double base = eval(); double exp = eval(); return pow (base, exp ); } default : return atof(s); } }
第 5 章 树与二叉树 5.1 树的概念 5.1.1 定义
5.1.2 术语
5.1.3 性质
5.2 二叉树的概念 5.2.1 定义 性质 定义
性质
5.2.2 存储结构 顺序
链式 typedef struct TreeNode { int data; struct TreeNode *left , *right ; } TreeNode, *Tree;
题目
5.3 二叉树的遍历 线索二叉树 要求掌握求二叉树深度的代码,判断是否为满二叉树的代码
int maxDepth (TreeNode* root) { if (root == NULL ) { return 0 ; } int leftDepth = maxDepth(root->left); int rightDepth = maxDepth(root->right); return (leftDepth > rightDepth ? leftDepth : rightDepth) + 1 ; } int countNodes (TreeNode* root) { if (root == NULL ) { return 0 ; } return 1 + countNodes(root->left) + countNodes(root->right); } int isFullBinaryTree (TreeNode* root) { int depth = maxDepth(root); int nodes = countNodes(root); return nodes == (1 << depth) - 1 ; }
5.3.1 二叉树的遍历 先序
void PreOrder (Tree T) { if (T != NULL ){ visit(T); PreOrder(T -> left); PreOrder(T -> right); } }
中序
void InOrder (Tree T) { if (T != NULL ){ InOrder(T -> left); visit(T); InOrder(T -> right); } }
后序
void PostOrder (Tree T) { if (T != NULL ){ PostOrder(T -> left); PostOrder(T -> right); visit(T); } }
5.3.2 线索二叉树*
题目 对于前序、中序找后序,树的结点确定顺序=前序
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef char ElementType;typedef struct BiTNode { ElementType data; struct BiTNode *lchild ; struct BiTNode *rchild ; } BiTNode, *BiTree; BiTree CreatBinTree (char *pre, char *in, int n) ; void postorder (BiTree T) ;int main () { BiTree T; char prelist[100 ]; char inlist[100 ]; int length; scanf ("%s" , prelist); scanf ("%s" , inlist); length = strlen (prelist); T = CreatBinTree(prelist, inlist, length); postorder(T); return 0 ; } void postorder (BiTree T) { if (T) { postorder(T->lchild); postorder(T->rchild); printf ("%c" , T->data); } } BiTree CreatBinTree (char *pre, char *in, int n) { BiTree T; int i; if (n <= 0 ) return NULL ; T = (BiTree)malloc (sizeof (BiTNode)); T->data = pre[0 ]; for (i = 0 ; in[i] != pre[0 ]; i++) ; T->lchild = CreatBinTree(pre + 1 , in, i); T->rchild = CreatBinTree(pre + i + 1 , in + i + 1 , n - i - 1 ); return T; }
统计二叉树度为1的结点个数。
#include <iostream> using namespace std;typedef struct BiNode { char data; struct BiNode *lchild, *rchild; } BiTNode, *BiTree; void CreateBiTree (BiTree &T) { char ch; cin >> ch; if (ch == '#' ) T = NULL ; else { T = new BiTNode; T->data = ch; CreateBiTree (T->lchild); CreateBiTree (T->rchild); } } int NodeCount (BiTree T) { if (T == NULL ) return 0 ; if (T->lchild == NULL && T->rchild != NULL ) return 1 + NodeCount (T->rchild); if (T->lchild != NULL && T->rchild == NULL ) return 1 + NodeCount (T->lchild); return NodeCount (T->lchild) + NodeCount (T->rchild); } int main () { BiTree T; CreateBiTree (T); printf ("%d" , NodeCount (T)); return 0 ; }
计算二叉树深度。
#include <iostream> using namespace std;typedef struct BiNode { char data; struct BiNode *lchild, *rchild; } BiTNode, *BiTree; void CreateBiTree (BiTree &T) { char ch; cin >> ch; if (ch == '#' ) T = NULL ; else { T = new BiTNode; T->data = ch; CreateBiTree (T->lchild); CreateBiTree (T->rchild); } } int Depth (BiTree T) { int m, n; if (T == NULL ) return 0 ; else { m = Depth (T->lchild); n = Depth (T->rchild); if (m > n) return (m + 1 ); else return (n + 1 ); } } int main () { BiTree tree; CreateBiTree (tree); cout << Depth (tree); return 0 ; }
#include <stdio.h> #include <stdlib.h> typedef struct TreeNode { int value; struct TreeNode *left , *right ; } TreeNode; TreeNode* buildTree (int * preorder, int * inorder, int inorderStart, int inorderEnd) { static int preorderIndex = 0 ; if (inorderStart > inorderEnd) return NULL ; TreeNode* node = (TreeNode*)malloc (sizeof (TreeNode)); node->value = preorder[preorderIndex++]; node->left = node->right = NULL ; if (inorderStart == inorderEnd) return node; int inorderIndex; for (inorderIndex = inorderStart; inorderIndex <= inorderEnd; inorderIndex++) { if (inorder[inorderIndex] == node->value) break ; } node->left = buildTree(preorder, inorder, inorderStart, inorderIndex - 1 ); node->right = buildTree(preorder, inorder, inorderIndex + 1 , inorderEnd); return node; } void mirrorTree (TreeNode* root) { if (root == NULL ) return ; TreeNode* temp = root->left; root->left = root->right; root->right = temp; mirrorTree(root->left); mirrorTree(root->right); } void levelOrderTraversal (TreeNode* root, int n) { if (root == NULL ) return ; TreeNode **queue = (TreeNode**)malloc (n * sizeof (TreeNode*)); int front = 0 , rear = 0 , count = 0 ; queue [rear++] = root; while (front < rear) { TreeNode* current = queue [front++]; printf ("%d" , current->value); if (++count < n) printf (" " ); if (current->left) queue [rear++] = current->left; if (current->right) queue [rear++] = current->right; } free (queue ); } int main () { int n; scanf ("%d" , &n); int inorder[n], preorder[n]; for (int i = 0 ; i < n; i++) { scanf ("%d" , &inorder[i]); } for (int i = 0 ; i < n; i++) { scanf ("%d" , &preorder[i]); } TreeNode* root = buildTree(preorder, inorder, 0 , n - 1 ); mirrorTree(root); levelOrderTraversal(root, n); return 0 ; }
5.4 树 森林 5.4.1 树的存储结构 双亲表示法
typedef struct Node { int data; int parent; }Node; typedef struct Tree { Node nodes[100 ]; int n; }Tree;
孩子表示法
孩子兄弟表示法 此方法就是将树转换为二叉树的方法
typedef struct Node { int data; struct Node *firstChild , *next Sibling ; }
5.4.2 转换 树->二叉树
森林->二叉树
二叉树->森林
5.4.3 遍历
5.5 应用 5.5.1 哈夫曼树 哈夫曼编码 定义
构造
哈夫曼编码 是可变长度编码
是前缀编码(没有任何编码是另一个编码的前缀)
5.5.2 并查集 它支持两种操作:
查找(Find) :确定某个元素属于哪个子集。
合并(Union) :将两个子集合并成一个集合。
parent[i]
表示元素 i
的父节点
int parent[100 ];void init (int n) { for (int i = 0 ; i < n; i++) parent[i] = i; } int find (int x) { if (parent[x] == x) return x; return find(parent[x]); } void unionSets (int x, int y) { int xRoot = find(x), yRoot = find(y); if (xRoot != yRoot) parent[xRoot] = yRoot; }
第 6 章 图 6.1 概念
概念参考 离散数学 期末复习 第5章
题目 在有n个顶点的有向图中,若要使任意两点间可以互相到达,则至少需要 n 条弧
6.2 存储结构和操作 6.2.1 邻接矩阵
typedef struct Graph { int V[MAXN]; int Edge[MAXN][MAXN]; int n, m; }Graph;
邻接矩阵的性质参考 离散数学 期末复习 第5章
6.2.2 邻接表
typedef struct AdjListNode { int dest; struct AdjListNode * next ; }AdjListNode; typedef struct AdjList { int data; struct AdjListNode * head ; }AdjList; typedef struct Graph { int n, m; struct AdjList * array ; }Graph;
6.2.3 十字链表 注意弧头是有向边的终点,弧尾是有向边的起点
6.2.4 邻接多重表
题目 要求建立一个无向图,采用邻接表做为存储结构。 例如
输入信息为:第一行给出图的顶点数n和边数e。第二行给出n个字符,表示n个顶点的数据元素的值。后面是e行,给出每一条边的两个顶点编号。
输出每个顶点的值以及各顶点的邻接点的值。
输入样例为: 7 9 0123456 0 2 0 3 0 4 1 3 1 5 2 3 2 5 4 5 5 6 输出样例为 0: 4 3 2 1: 5 3 2: 5 3 0 3: 2 1 0 4: 5 0 5: 6 4 2 1 6: 5
#include <stdio.h> #include <stdlib.h> #define MVNum 100 typedef struct ArcNode { int adjvex; struct ArcNode *nextarc ; } ArcNode; typedef struct VNode { char data; ArcNode *firstarc; } VNode, AdjList[MVNum]; typedef struct { AdjList vertices; int vexnum, arcnum; } ALGraph; void CreatMGraph (ALGraph *G) ; void printGraph (ALGraph G) ; int main () { ALGraph G; CreatMGraph(&G); printGraph(G); return 0 ; } void CreatMGraph (ALGraph *G) { int i, j, k; ArcNode *s; scanf ("%d%d" , &G->vexnum, &G->arcnum); getchar(); for (i = 0 ; i < G->vexnum; i++) scanf ("%c" , &G->vertices[i].data); for (i = 0 ; i < G->vexnum; i++) G->vertices[i].firstarc = NULL ; for (k = 0 ; k < G->arcnum; k++) { scanf ("%d%d" , &i, &j); s = (ArcNode *)malloc (sizeof (ArcNode)); s->adjvex = j; s->nextarc = G->vertices[i].firstarc; G->vertices[i].firstarc = s; s = (ArcNode *)malloc (sizeof (ArcNode)); s->adjvex = i; s->nextarc = G->vertices[j].firstarc; G->vertices[j].firstarc = s; } } void printGraph (ALGraph G) { int i, j; ArcNode *p; for (i = 0 ; i < G.vexnum; i++) { printf ("%c:" , G.vertices[i].data); for (p = G.vertices[i].firstarc; p; p = p->nextarc) printf (" %c" , G.vertices[p->adjvex].data); printf ("\n" ); } }
6.3 遍历 6.3.1 广度优先搜索 BFS 可能要求代码实现
6.3.2 深度优先搜索 DFS 可能要求代码实现
6.3.3 连通性
题目
#include <iostream> #include <queue> #include <vector> using namespace std;struct peo { int id, level; }; int main () { int n, temp, maxlevel = -1 ; queue<peo> q; vector<peo> ans; cin >> n; vector<vector<int >> v (n+1 ); for (int i = 1 ; i <= n; i++) { cin >> temp; if (temp == -1 ) temp = 0 ; v[temp].push_back (i); } q.push ({0 ,0 }); while (!q.empty ()) { peo p = q.front (); int id = p.id, level = p.level; if (p.level > maxlevel) maxlevel = p.level; ans.push_back (p); q.pop (); for (int i = 0 ; i < v[id].size (); i++) q.push ({v[id][i], level + 1 }); } cout << maxlevel << endl; for (int i = 0 ; i < ans.size (); i++) { if (ans[i].level == maxlevel) { cout << ans[i].id; if (i != ans.size () - 1 ) cout << " " ; } } return 0 ; }
题目链接:https://pintia.cn/problem-sets/994805046380707840/problems/994805061769609216
#include <bits/stdc++.h> using namespace std;const int N = 1e5 +10 ;int n;struct people { int sex,father=-1 ,mother=-1 ; }peo[N]; bool st[N],flag;void dfs (int cur,int generation) { if (cur==-1 ) return ; if (generation>5 ) return ; st[cur]=1 ; dfs (peo[cur].father,generation+1 ); dfs (peo[cur].mother,generation+1 ); } void finddfs (int cur,int generation) { if (cur==-1 ) return ; if (generation>5 ) return ; if (st[cur]) flag=true ; finddfs (peo[cur].father,generation+1 ); finddfs (peo[cur].mother,generation+1 ); } int main () { cin>>n; int id,father,mother; string sex; for (int i=0 ;i<n;i++) { cin>>id>>sex; if (sex=="M" ) peo[id].sex=1 ; else peo[id].sex=0 ; cin>>peo[id].father>>peo[id].mother; peo[peo[id].father].sex=1 ; peo[peo[id].mother].sex=0 ; } cin>>n; int a,b; for (int i=0 ;i<n;i++) { cin>>a>>b; if (peo[a].sex==peo[b].sex) puts ("Never Mind" ); else { memset (st,false ,sizeof st); dfs (a,1 ); flag=false ; finddfs (b,1 ); if (flag) puts ("No" ); else puts ("Yes" ); } } return 0 ; } 作者:GRID 链接:https: 来源:AcWing 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
6.4 应用 6.4.1 最小生成树
Prim 算法 可能要求代码实现
Kruskal 算法 可能要求代码实现
int find (int x) { if (parent[x] != x) { parent[x] = find(parent[x]); } return parent[x]; } void union_set (int x, int y) { int rootX = find(x); int rootY = find(y); if (rootX != rootY) { if (ranks[rootX] < ranks[rootY]) { parent[rootX] = rootY; } else if (ranks[rootX] > ranks[rootY]) { parent[rootY] = rootX; } else { parent[rootY] = rootX; ranks[rootX]++; } } } int kruskal () { int mst_cost = 0 , edges_selected = 0 ; qsort(edges, M, sizeof (edges[0 ]), cmp); for (int i = 0 ; i < N; i++) { parent[i] = i; ranks[i] = 0 ; } for (int i = 0 ; i < M && edges_selected < N - 1 ; i++) { int u = edges[i].u; int v = edges[i].v; if (find(u) != find(v)) { union_set(u, v); mst_cost += edges[i].cost; edges_selected++; } } if (edges_selected != N - 1 ) { return -1 ; } return mst_cost; }
题目
6.4.2 最短路径 Dijkstra 算法 不要求代码实现,要会画求解过程的表格
Floyd 算法 可能要求算法实现
题目
#include <stdio.h> #include <limits.h> #define MAXN 100 #define INF INT_MAX int n, e;int dist[MAXN][MAXN];void initialize () { for (int i = 0 ; i < n; i++) { for (int j = 0 ; j < n; j++) { if (i == j) dist[i][j] = 0 ; else dist[i][j] = INF; } } } void floydWarshall () { for (int k = 0 ; k < n; k++) { for (int i = 0 ; i < n; i++) { for (int j = 0 ; j < n; j++) { if (dist[i][k] != INF && dist[k][j] != INF && dist[i][j] > dist[i][k] + dist[k][j]) { dist[i][j] = dist[i][k] + dist[k][j]; } } } } } int main () { while (scanf ("%d %d" , &n, &e) != EOF) { initialize(); int a, b, c; for (int i = 0 ; i < e; i++) { scanf ("%d %d %d" , &a, &b, &c); dist[a][b] = c; dist[b][a] = c; } floydWarshall(); int minDist = INF, minCity = 0 ; for (int i = 0 ; i < n; i++) { int sum = 0 ; for (int j = 0 ; j < n; j++) { sum += dist[i][j]; } if (sum < minDist) { minDist = sum; minCity = i; } } printf ("%d\n" , minCity); } return 0 ; }
6.4.3 有向无环图描述表达式
6.4.4 拓扑排序 可能要求代码实现
题目
#include <stdio.h> #include <stdlib.h> #define MAXN 10 #define MAXM 50 typedef struct Node { int vertex; struct Node * next ; } Node; int inDegree[MAXN];Node* graph[MAXN]; int topoOrder[MAXN];int stack [MAXN];int top = -1 ;void addEdge (int start, int end) { Node* newNode = (Node*)malloc (sizeof (Node)); newNode->vertex = end; newNode->next = graph[start]; graph[start] = newNode; inDegree[end]++; } int topologicalSort (int n) { int count = 0 ; for (int i = 1 ; i <= n; i++) { if (inDegree[i] == 0 ) { stack [++top] = i; } } while (top != -1 ) { int current = stack [top--]; topoOrder[count++] = current; Node* temp = graph[current]; while (temp) { int adjVertex = temp->vertex; inDegree[adjVertex]--; if (inDegree[adjVertex] == 0 ) { stack [++top] = adjVertex; } temp = temp->next; } } if (count != n) { return 0 ; } return 1 ; } int main () { int n, m, u, v; scanf ("%d %d" , &n, &m); for (int i = 0 ; i < m; i++) { scanf ("%d %d" , &u, &v); addEdge(u, v); } if (topologicalSort(n)) { for (int i = 0 ; i < n; i++) { printf ("%d " , topoOrder[i]); } printf ("\n" ); } else { printf ("0\n" ); } return 0 ; }
第 7 章 查找 7.1 概念
7.2 顺序查找和二分查找 7.2.1 顺序查找 线性表的顺序查找 要求掌握带哨兵的代码实现。哨兵为a[0],从后往前找,就不用判断数组是否越界
有序表的顺序查找
7.2.2 二分查找
int binarySearch (int a[], int val) { int left = 0 , right = n - 1 , mid; while (left <= right){ mid = (left + right) / 2 ; if (a[mid] == val) return mid; else if (a[mid] > val) right = mid - 1 ; else left = mid + 1 ; } return -1 ; }
7.2.3 分块查找*
7.3 树形查找 7.3.1 二叉排序树 BST 不要求代码实现
7.3.2 平衡二叉树 AVL
题目 删除根节点时,倾向于把前驱拿上来
7.5 哈希表 7.5.1 概念
7.5.2 哈希函数
7.5.3 冲突 注意是 mod m, 不是 mod k
7.5.4 哈希查找和性能分析 要求会构造哈希表,计算成功和失败查找的平均查找长度
题目
第 8 章 排序 8.1 概念
8.2 插入排序 8.2.1 直接插入 要求代码实现
void InsertSort (int a[], int n) { int i, j; for (i = 2 ; i <= n; i++){ if (a[i] < a[i - 1 ]){ a[0 ] = a[i]; for (j = i - 1 ; a[0 ] < a[j]; j--) a[j + 1 ] = a[j]; a[j + 1 ] = a[0 ] } } }
8.2.2 二分插入 要求代码实现
void InsertSort (int a[], int n) { int i, j, l, r, mid; for (i = 2 ; i <= n; i++){ a[0 ] = a[i]; l = 1 , r = i - 1 ; while (l <= r){ mid = (l + r) / 2 ; if (a[mid] > a[0 ]) r = mid - 1 ; else l = mid + 1 ; } for (j = i - 1 ; j >= r + 1 ; j--) a[j + 1 ] = a[j]; a[j + 1 ] = a[0 ]; } }
8.3 交换排序 8.3.1 冒泡排序
8.3.2 快速排序 要求代码实现
void qsort (int a[], int l, int r) { if (l < r){ int pivot = partition(a, l, r); qsort(a, l, pivot - 1 ); qsort(a, pivot + 1 , r); } } int partition (int a[], int l, int r) { int pivot = a[l]; while (l < r){ while (l < r && a[r] >= pivot) r--; a[l] = a[r]; while (l < r && a[l] <= pivot) l++; a[r] = a[l]; } a[l] = pivot; return l; }