目录
原始版思路和代码
其中数据域存放一个字符,下地址是按字母顺序排列的下一个元素下标值
例如:
~ | 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;
}