数组模拟链表——静态链表的优势

目录

原始版思路和代码

更新版——模拟数组插入和删除

标准题解版

拓展——AcWing826题单链表


原始版思路和代码

其中数据域存放一个字符,下地址是按字母顺序排列的下一个元素下标值

例如:

~ m a s q
2 4 1 0 3

在这个表格中,~ 表示开始字符,它的下地址域是2,表示下标为2的字母a是所有字母中的最小字母,而字母a对应的next下地址域是1,表示按顺序下一个字母是下标为1的字母m...沿着下地址域,字母按顺序分别为a-m-q-s,最后一个字符的下地址为0。

输入格式:输入两行,第一行是一个正整数num,表示输入字符个数,第二行是num个小写字母(无空格);

输出格式:两行。第一行是下地址域内容,空格隔开,第二行是沿下地址方向输出字母。

输入:

4

masq

输出:

2 4 1 0 3

a m q s ~

实现代码如下

#include <iostream>
#include<stdio.h>
using namespace std;
#define MaxSize 105
typedef struct//模拟链表的结构
{
    char ch;
    int next;
}ElemType;

typedef struct {
    ElemType arr[MaxSize];
    int length;
}SqList;

int main()
{
	int num, i, j, a[MaxSize], t1;
	SqList L, t;
    L.length = 0;
    cin >> num;
    getchar();
    L.arr[0].ch = '~';
    a[0] = 0;
    for(i = 1; i <= num; i ++)
    {
        cin >>L.arr[i].ch;
        L.length ++;
        a[i] = i;
    }
    for(i = 0; i <= num-1; i ++)//采用冒泡排序,按照ASCII码值开始对输入的字母进行排序
    {
        for(j = i + 1; j <= num; j ++)
        {
            if(L.arr[i].ch > L.arr[j].ch )
            {
                t.arr[0].ch = L.arr[i].ch; t1 = a[i];
                L.arr[i].ch = L.arr[j].ch; a[i] = a[j];
                L.arr[j].ch = t.arr[0].ch; a[j] = t1;
            }  
        }
    }
    i = 0;
    j = 0;
    while(num >= 0)//最关键的部分,把下地址域的各个值对应排好序的数组a
    {
        L.arr[i].next = a[j];
        i = a[j];
        j ++;
        num --;
    }

    num = L.length;//num在上一个循环减为了0,此处要重新赋值
    for(i = 0; i <= num; i ++)
    {
        if(i == num) cout << L.arr[i].next;
        else cout << L.arr[i].next << " ";//输出下地址域的内容
    }
    cout << endl;
    for(i = 0; i <= num; i ++)
    {
        cout << L.arr[i].ch << " ";//沿下地址方向输出字母
    }
    
    return 0;
}

输出如下图

更新版——模拟数组插入和删除

更新,之前是自己想的办法,逻辑和语言描述方面有些欠缺,更新了y总的讲解

数组实现的静态链表在时间上比指针实现的动态链表快得多,因为C++中new一个新的指针非常耗时

// head 表示头结点的下标
// e[i] 表示节点i的值
// ne[i] 表示节点i的next指针是多少
// idx 存储当前已经用到了哪个点

// 初始化
void init()
{
    head = -1;
    idx = 0;
}
// 将x插到头结点
void add_to_head(int x)
{
    e[idx] = x;
    ne[idx] = head;
    head = idx ++ ;
}
// 将x插到下标是k的点后面
void add(int k, int x)
{
    e[idx] = x;
    ne[idx] = ne[k];
    ne[k] = idx ++ ;
}

删除只需要一句话就可以了,在算法里面不用管空间的浪费,用空间换取时间

// 将下标是k的点后面的点删掉
void remove(int k)
{
    ne[k] = ne[ne[k]];
}

这句话在指针里面就是p->next = p->next->next,即跳过一个节点就是删除了

标准题解版

#include <iostream>
#include<stdio.h>
using namespace std;
#define MaxSize 105
typedef struct//模拟链表的结构
{
    char ch;
    int next;
}ElemType;
 
typedef struct {
    ElemType *arr;
    int length;
}SqList;
void input(SqList &L,char x)
{
	L.arr[L.length].ch=x;
	for(int i=0;i!=-1;i=L.arr[i].next)
	{
		int n=L.arr[i].next;
		if(L.arr[n].ch>x||n==-1)
		{
			L.arr[L.length].next=n;
			L.arr[i].next=L.length;
			L.length++;
			return;
		}
	}
 } 
void intlist(SqList &L,int num)
{
	L.arr=new ElemType[MaxSize];
	L.arr[0].ch='~';
	L.arr[0].next=-1;
	L.length=1;
	for(int i=1;i<=num;i++)
	{
		char c;
		cin>>c;
		input(L,c);
	}
}

 void output(SqList L)
 {
 	for(int i=0;i<L.length;i++)
 	{
 		if(i!=0)
 		{
 			cout<<" "; 
		}
		if(L.arr[i].next<0) cout<<0;
		else cout<<L.arr[i].next;
	}
	cout<<endl;
	for(int i=L.arr[0].next;i!=-1;i=L.arr[i].next)
	{
		cout<<L.arr[i].ch<<" ";
	}
	cout<<"~"<<" ";
}
int main()
{
	SqList L;
	int num;
 	cin>>num;
 	intlist(L,num);
 	output(L);
 	return 0;
}

拓展——AcWing826题单链表

#include <iostream>

using namespace std;

const int N = 100010;
int head, n[N], ne[N], idx;


void init()
{
    head = -1;
    idx = 0;
}

void add_H(int x)// 将x插到头结点
{
    e[idx] = x, ne[idx] = head, head = idx ++ ;
}

void add(int k, int x)// 将x插到下标是k的点后面

{
    e[idx] = x, ne[idx] = ne[k], ne[k] = idx ++ ;
}

// 将下标是k的点后面的点删掉
void remove(int k)
{
    ne[k] = ne[ne[k]];
}

int main()
{
    int m;
    cin >> m;

    init();

    while (m -- )
    {
        int k, x;
        char op;

        cin >> op;
        if (op == 'H')
        {
            cin >> x;
            add_H(x);
        }
        else if (op == 'D')
        {
            cin >> k;
            if (!k) head = ne[head];
            else remove(k - 1);
        }
        else
        {
            cin >> k >> x;
            add(k - 1, x);
        }
    }

    for (int i = head; i != -1; i = ne[i]) cout << e[i] << ' ';
    cout << endl;

    return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_74776728/article/details/130836698