链表相比于数组的优越在于链表的元素独立性较强,易于频繁插入或删除数据元素;缺点在于其不稳定性较大。
在线性表中,每个结点只需要存放后继结点的地址,让一个个元素串联起来,就能够形成一个“单向链表”
单向链表的结构体为
struct Node{
datatype data;
Node*next;
};
建立链表的过程可以描述为
生成头结点:
while(未结束){
生成新结点;
把新结点插入链表;}
c++有new和delete函数,更利于申请和释放空间
struct node{
int data;
node*next;
};
void CreateList(node*&head){
//引用的参数是表头指针
node*s,*p;
s=new node;
cin>>s->data;
while(s->data!=0){
if(head==NULL)head=s;//如果没有head,则插入head
else p->next=s;
p=s;
s= new node;//new函数为node重新分配内存
cin>>s->data;
}
p->next=NULL;
delete s;//释放堆内存
return;}
c语言无new,delete函数,一般是用malloc函数和free函数
typedef struct node{
int data;
node*next;
}Node;//为struct起个别名为Node
void CreateList(Node*&head){
Node *s,*p;
s=(Node*)malloc(sizeof(Node));
scanf("%d",&s->data);
while(s->data!=0){
if(head==NULL)head=s;
else p->next=s;
p=s;
s=(Node*)malloc(sizeof(Node));
scanf("%d",&s->data);
}
p->next=NULL;
free(s);
return;
}
遍历链表从表头指针开始,使用跟踪指针逐个输出结点值,直至指针为空
while(head){
printf("%d ",head->data;
head=head->next;
}
步骤
current = head, k = 0
if position is 0, insert num before head and return
while current != null
if position = k + 1
insert num after current
current = current.next, k ++
实例:用插入法生成有序链表
#include
using namespace std;
struct List{
int data;
List*next;
};
int main(){
int k;
List*head=NULL;
cin>>k;
while(k!=0){
List*s,*p,*q;int b=1;
s=new List;
s->data=k;
s->next=NULL;
if(head==NULL)head=s;//若表空,则建立一个结点的链表
else if(head->data>s->data){
//被插数据最小,插入表头
s->next=head;
head=s;
}
else {
for(q=head,p=head->next;p;q=p,p=p->next){
if(p->data>s->data){
s->next=p;
q->next=s;b=0;break;
}
}
if(b)q->next=s;
}
}
while(head){
cout<<head->data<<" ";
head=head->next;
}
return 0;
}
伪代码如下
current = head
return head if head.value is number
while current.next != null
current = current.next
if current.value is number
return current
即为
for(p=head;p;p=p->next,i++){
if(k==p->data)break;
}
printf("%d在链表中的第%d位",k,i);
伪代码为
if position is 0, head = head.next & return
current = head, k=0
while current.next != null
if position is k + 1
current.next=current.next.next
current = current.next, k ++
实例:从链表中删除值等于key的结点
这里我们构造一个函数
void del(List*&head,int key){
List*p;
if(!head){
printf("List is null");return;}
if(head->data==key){
p=head; head=head->next;
delete p;p=NULL;return;
}
for(List*i=head;i->next;i=i->next){
if(i->next->data==key){
p=i->next;
i->next=p->next;
delete p;
p=NULL;
}
}
}
计算理工学院有 N 个同学,围成了一个圆圈,每人被顺序地编了一个序号(分别为 1,2,3…n),从编号为 K 的人开始报 11,他之后(顺初始数字增长方向计算序号)的人报 2,以此类推,数到某一个数字 M 的人出列。出列同学的下一个人又从 1开始继续报数,数到某一个数字 M的人出列。不断重复这一过程,直到所有人都出列为止。
输入格式
测评机会反复运行你的程序。每次程序运行时,输入为一行,包括三个被空格分隔开的符合描述的正整数 N、K 和 M(10001≤K≤N≤1000, 20001≤M≤2000)
#include
#include
typedef struct node {
int data;
struct node *next;
} Node;
Node *circle_create(int n);
void count_off(Node *head, int n, int k, int m);
int main() {
int n, k, m;
scanf("%d%d%d", &n, &k, &m);
Node *head = circle_create(n);
count_off(head, n, k, m);
return 0;
}
Node *circle_create(int n) {
Node *temp, *new_node, *head;
int i;
// 创建第一个链表节点并加数据
temp = (Node *) malloc(sizeof(Node));
head = temp;
head->data = 1;
// 创建第 2 到第 n 个链表节点并加数据
for(i = 2; i <= n; i++) {
new_node = (Node *) malloc(sizeof(Node));
new_node->data = i;
temp->next = new_node;
temp = new_node;
}
// 最后一个节点指向头部构成循环链表
temp->next = head;
return head;
}
void count_off(Node *head, int n, int k, int m) {
Node *p, *q;
p = head;
q = head;
for (; p->next != head; p = p->next);
for (int i = -k + 2; q != q->next; i++,p=q,q=q->next) {
if (i == m) {
printf("%d ", q->data);
p->next = q->next;
free(q);
q = p;
i = 0;
}
}
printf("%d", q->data);
}