赞
踩
众所周知,链表是通过指针将所有的结点相连接,以此来达到快速插入和删除的数据结构。但是在
很多时候,特别是在学校、书本里面,大多都是用的结构体,而使用结构体的劣势也显而易见:前戏长,运算慢。在我们平时做算法题还是练习的时候,我们推荐使用数组模拟。
当然,队列、栈、二叉树 这些也可以用数组模拟。
- // 定义结构体
- typedef struct LNode {
- ElemType data;
- struct LNode *next;
- }LNode, *LinkList;
-
-
- // 在单链表中取得第i个元素
- Status getElem L(LinkList L,int i,ElemType &e) {
- // L为带头结点的单链表指针。
- // 当第i个元素存在时,其赋给e并返回,否则返回Error。
- p = L->next, j=1; // 初始化,p指向第一个结点,j为计数器。
- while(p && j<i) { // 从头结点开始查找,知道p指向第i个结点或 p 为空
- p = p->next ;
- ++j;
- }
- if(!p ||j>i) return ERROR; // 第i个元素不存在
- e = p-> data; // 取第i个元素并返回
- return e;
- }
- // 在单链表中第i个位置之前插入元素e
- Status ListInsert L(LinkList &L,int i, ElemType e) { // & 返回哪个参数
- p = L , j=0;
- while(p && j < i-1) { // 寻找第i-1个结点
- p = p-> next;
- ++j;
- }
- if(!p || j>i-1) return ERROR; // i小于1 或者 i大于表长+1(健壮性处理)
- s = (LinkList)malloc (sizeof LNode);
- s->data = e;
- s->next = p->next;
- p -> next = s;
- // 指针操作,注意前后顺序
- }
- // 在单链表中删除第i个元素 并返回删除的值为e
- Status ListDelete L(LinkList &L,int i,ElemType &e) {
- p = L,j=0; // 初始化
- while(p->next && j<i-1){
- p = p->next ;
- ++j;
- }
- if(!(p->next) || j>i-1) return ERROR;
- q = p->next ;
- p->next = q->next; // 删除并释放结点(q)
- e = q->data;
- free(q);
- // 注意操作顺序
- }
-
-
-
-
-
-
-
定义变量: idx,head , h[ ], ne[ ] , e[ ] 。
idx:链表的下标。 在进行删除,插入操作时作为辅助元素帮助操作。
head:链表头结点。
ne[]:指向当前元素位置的下一个位置。
e[]:保存当前节点的值。
定义基本方法:init_list() 、 insert_head() 、add() 、 remove() 。
-
- // 对链表进行初始化。
- void init_list(){
- idx = 0; // 令当前下标0 (c++全局变量初试为0)
- head = -1; // 链表的头节点要指向-1
- }
-
- //将x插入到头节点上
- void insert_head(int x) {
- e[idx] = x; //第一步,先将值放进去
- ne[idx] = head; //head作为一个指针指向上一个头结点,现在ne[idx] = head 相当于 新添加的元素
- // 指向上一个更新的头结点。
- head = idx; //更新head结点进行迭代。
- idx ++; //指针向下移一位。
- }
-
- //将x插入到下标为k的点的后面
- void add(int k, int x){
- e[idx] = x;//先将元素插进去
- ne[idx] = ne[k];//让元素x配套的指针,指向它要占位的元素的下一个位置
- ne[k] = idx;//让原来元素的指针指向自己
- idx ++;//将idx向后挪
- }
-
- //将下标是k的结点后面的点删除
- void remove(int k){
- ne[k] = ne[ne[k]]; //让k的指针指向k下一个结点的下一个结点 。
- }
值得注意的是 ,在数组模拟链表这几个基本方法中,需尤为注意操作的顺序。例如:在 add() 方法中,如果把
ne[idx] = ne[k] 和 ne[k] = idx 互换位置 ,那结果就不一样了, 因为在其之前, ne[k] 的位置已经不一样了 ,这个时候再去指向 ne[k] 就错了。
借鉴 Acwing 里面一道模板题
思路:定义好基本变量后 ,使用数组模拟链表或者使用c++自带的STL(之前在洛谷看到过一句话,很深刻:我们通过努力去尝试AC的每一道题,不是目标,而是训练。所以说学习这种东西真的是多多益善 0.0) 。然后写好各自方法体。
AC代码:
- #include <iostream>
- #include <algorithm>
- using namespace std;
- const int N = 100010;
- int head, e[N],h[N],ne[N], idx;
- int n;
- void init(){
- head = -1;
- idx = 0;
- }
- // 头结点插值
- void inset_head(int x){
- e[idx] = x;
- ne[idx] = head;
- head = idx;
- idx ++ ;
- }
- // 将x插入到下标是k的结点的后面
- void add(int k, int x){
- e[idx] = x;
- ne[idx] = ne[k];
- ne[k] = idx;
- idx ++ ;
- }
- // 将k点后面的点删除
- void remove(int k){
- ne[k] = ne[ne[k]];
- }
- int main(){
- cin >> n;
- init();
- while (n--){
- int k, x;
- char op;
-
- cin >> op;
- if (op == 'H'){
- cin >> x;
- inset_head(x);
- }
- else if (op == 'D'){
- cin >> k;
- if (!k) head = ne[head];
- remove(k - 1);
- }
- else{
- cin >> k >> x;
- add(k - 1, x);
- }
- }
- for (int i = head; i != -1; i = ne[i]) cout << e[i] <<" ";
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。