《算法笔记》7.3小节——数据结构专题(1)->链表处理
链表是数据结构中一种最基本的数据结构,它是用链式存储结构实现的线性表。它较顺序表而言在插入和删除时不必移动其后的元素。现在给你一些整数,然后会频繁地插入和删除其中的某些元素,会在其中某些时候让你查找某个元素或者输出当前链表中所有的元素。
下面给你基本的算法描述:
输入数据只有一组,第一行有n+1个整数,第一个整数是这行余下的整数数目n,后面是n个整数。这一行整数是用来初始化列表的,并且输入的顺序与列表中的顺序相反,也就是说如果列表中是1、2、3那么输入的顺序是3、2、1。
第二行有一个整数m,代表下面还有m行。每行有一个字符串,字符串是“get”,“insert”,“delete”,“show”中的一种。如果是“get”或者“delete”,则其后跟着一个整数a,代表获得或者删除第a个元素;如果是“insert”,则其后跟着两个整数a和e,代表在第a个位置前面插入e;“show”之后没有整数。
如果获取成功,则输出该元素;如果删除成功则输出“delete OK”;如果获取失败或者删除失败,则输出“get fail”以及“delete fail”。如果插入成功则输出“insert OK”,否则输出“insert fail”。如果是“show”则输出列表中的所有元素,如果列表是空的,则输出“Link list is empty”。注:所有的双引号均不输出。
3 3 2 1
21
show
delete 1
show
delete 2
show
delete 1
show
delete 2
insert 2 5
show
insert 1 5
show
insert 1 7
show
insert 2 5
show
insert 3 6
show
insert 1 8
show
get 2
1 2 3
delete OK
2 3
delete OK
2
delete OK
Link list is empty
delete fail
insert fail
Link list is empty
insert OK
5
insert OK
7 5
insert OK
7 5 5
insert OK
7 5 6 5
insert OK
8 7 5 6 5
7
#include//malloc func
#include//stdio func
#include//strcmp func
#define OK 1
#define ERROR 0
typedef int Status;//function type
typedef int ElemType;//LNode data type
typedef struct LNode{
ElemType data;//data element definition
struct LNode *next;//next node address definition
}LNode, *LinkList;//node type & list type definition
Status GetElem_L(LinkList &L,int i, ElemType &e){
//L is head node
LinkList p;
p=L->next;
int j=1;//p is the 1st node(next to L), j is a counter
while (p&&jnext;
++j;
}
if (!p||j>i)//node i is not exist
return ERROR;
e=p->data;//e is data of node i
return OK;
}
Status ListInsert_L(LinkList &L, int i,ElemType e){
//insert new data before node i
LinkList p,s;//definition of new node(s),node i-1(p)
p=L;
int j=0;
while(p&&jnext;
++j;
}
if(!p||j>i-1)//if i<1 or i>length of list, return ERROR
return ERROR;
s=(LinkList)malloc(sizeof(LNode));//insert new node as node i-1
s->data=e;
s->next=p->next;
p->next=s;
return OK;
}
Status ListDelete_L(LinkList &L,int i,ElemType &e){
//delete node i,and return the data by e(by address transmission)
LinkList p,q;
p=L;
int j=0;
while(p->next&&jnext;
++j;
}
if(!(p->next)||j>i-1)//delete isn't exist
return ERROR;
q=p->next;
p->next=q->next;//delete and free node
e=q->data;
free(q);
return OK;
}
void CreateList_L(LinkList &L,int n){
//input a list from rear to start
LinkList p;
int i;//the length of list
L=(LinkList)malloc(sizeof(LNode));
L->next=NULL;//head node allocate
for(i=n;i>0;--i){
p=(LinkList)malloc(sizeof(LNode));//new node between head node(L) and L->next
scanf("%d",&p->data);
p->next=L->next;
L->next=p;
}
}
void ShowList_L(LinkList &L){
//show data of L
LinkList p=L->next;//p is a node to show L
if(p==NULL)
{
printf("Link list is empty\n");
return;
}
while(p!=NULL){
if(p->next==NULL)
printf("%d",p->data);
else printf("%d ",p->data);
p=p->next;
}
printf("\n");
}
int main(){
int n=0,m=0,num=0;
ElemType e;
char str_Instruction[10];
LinkList List;
scanf("%d",&n);
CreateList_L(List,n);
scanf("%d",&m);
while(m--){
scanf("%s",str_Instruction);
if(!strcmp(str_Instruction,"get")){
scanf("%d",&num);
if(GetElem_L(List,num,e)){
printf("%d\n",e);
}
else{
printf("get fail\n");
}
}
else if(!strcmp(str_Instruction,"delete")){
scanf("%d",&num);
if(ListDelete_L(List,num,e)){
printf("delete OK\n");
}
else{
printf("delete fail\n");
}
}
else if(!strcmp(str_Instruction,"insert")){
scanf("%d %d",&num,&e);
if(ListInsert_L(List,num,e)){
printf("insert OK\n");
}
else{
printf("insert fail\n");
}
}
else if(!strcmp(str_Instruction,"show")){
ShowList_L(List);
}
}
return 0;
}
已有a、b两个链表,每个链表中的结点包括学号、成绩。要求把两个链表合并,按学号升序排列。
第一行,a、b两个链表元素的数量N、M,用空格隔开。 接下来N行是a的数据 然后M行是b的数据 每行数据由学号和成绩两部分组成
按照学号升序排列的数据
2 3
5 100
6 89
3 82
4 95
2 10
2 10
3 82
4 95
5 100
6 89
#include
struct node {
int num;
int score;
node *next;
};
void insert(node *ans, node *q) { //ans为最终的打印链表,q为插入的一个人的学号和分数的结点
node *pre, *p; //新建两个节点
pre = ans, p = ans->next;
while (p != NULL && p->num < q->num) { //找到第一个学号比q大的结点
pre = p;
p = p->next;
}
pre->next = q; // pre-q-p连接
q->next = p;
}
int main() {
node *ans, *p;
int n, m;
scanf("%d %d", &n, &m);
ans = new node;
ans->next = NULL;
for (int i = 0; i < n + m; i++) {
p = new node;
p->next = NULL;
scanf("%d %d", &p->num, &p->score);
insert(ans, p); //将新结点连入链表中
}
for (p = ans->next; p != NULL; p = p->next) {
printf("%d %d\n", p->num, p->score);
}
return 0;
}
这个之前一直没想到,其实是每次创建新结点后,通过遍历找到其应该插入的位置即可实现排序。