链表

说到链表,不得不提指针。。。虽然个人一点不喜欢指针,但为了链表也得学。

链表基本操作:

1.类型和变量的说明
struct Node
{ int data;
Node *next;
};
Node *p;
2.申请存储单元 //动态申请、空间大小由指针变量的基类型决定
p=new Node;
3.指针变量的赋值
指针变量名=NULL; //初始化,暂时不指向任何存储单元
如何表示和操作指针变量?不同于简单变量(如A=0;),c++规定用“指针变量名->”的形式引用指针变量(如P->data=0;)。

这里还有一个为了用链表而用链表的代码,大家过目:

#include<iostream>
using namespace std;
struct Node {
    int data;
    Node *next;
};
Node *head,*p,*r; //r指向链表的当前最后一个结点,可以称为尾指针
int x;
int main() {
    cin>>x;
    head=new Node; //申请头结点
    r=head;
    while(x!=-1) { //读入的数非-1
        p=new Node; //则,申请一个新结点
        p->data=x;
        p->next=NULL;
        r->next=p; //把新结点链接到前面的链表中,实际上r是p的直接前趋
        r=p; //尾指针后移一个
        cin>>x;
    }
    p=head->next; //头指针没有数据,只要从第一个结点开始就可以了}
    while(p->next!=NULL) {
        cout<<p->data<<" ";
        p=p->next;
    }
    cout<<p->data<<endl; //最后一个结点的数据单独输出
    return 0;
}

单链表:

1. 查找“数据域满足一定条件的结点”
p=head->next;
while((p->data!=x)&&(p->next!=NULL) p=p->next; //找到第一个就结束
if(p->data==x)找到了处理;
else 输出不存在;
2
如果想找到所有满足条件的结点,则修改如下:
p=head->next;
while(p->next!=NULL) //一个一个判断
{
if(p->data==x)找到一个处理一个;
p=p->next;
}

这都很简单,所以我们引入双向链表,顺便在双向链表中练习插入节点和删除节点。

【数据结构的定义】:
struct node
{
int data;
node *pre,*next; //pre指向前趋,next指向后继
}
node *head,*p,*q,*r;

插入节点:

void insert(node *head,int i,int x) { //在双向链表的第i个结点之前插入X
    node *s,*p;
    int j;
    s=new node;
    S->data=x;
    P=head;
    j=0;
    while((p->next!=NULL)&&(j<i)) {
        p=p->next;
        j=j+1;
    } //p指向第i个结点
    if(p==NULL) cout<<"no this position!";
    else { //将结点S插入到结点P之前
        s->pre=p->pre; //将S的前趋指向P的前趋
        p->pre=s; //将S作为P的新前趋
        s->next=p; //将S的后继指向P
        p->pre->next=s; //将P的本来前趋结点的后继指向S
    }
}

删除节点:

void delete(node *head,int i) { //删除双向链表的第i个结点
    int j;
    node *p;
    P=head;
    j=0;
    while((p->next!=NULL)&&(j<i)) {
        p=p->next;
        j=j+1;
    } //p指向第i个结点
    if(p==NULL) cout<<"no this position!";
    else { //将结点P删除
        p->pre->next=p->next; //P的前趋结点的后继赋值为P的后继
        p->next->pre=p->pre; //P的后继结点的前趋赋值为P的前趋
    }
}

这里还有一个代码,为约瑟夫问题

描述
约瑟夫问题:有n只猴子,按顺时针方向围成一圈选大王(编号从1到n),从第1号开始报数,一直数到m,数到m的猴子退出圈外,剩下的猴子再接着从1开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王,编程求输入n,m后,输出最后猴王的编号。

输入
每行是用空格分开的两个整数,第一个是 n, 第二个是 m ( 0 < m,n <=300)。最后一行是:

0 0

输出
对于每行输入数据(最后一行除外),输出数据也是一行,即最后猴王的编号
样例输入
6 2
12 4
8 3
0 0
样例输出
5
1
7
代码如下:
#include<iostream> #include<cstdio> using namespace std; struct node { long d; node *next; }; long n,m; node *head,*p,*r; int main() { long i,j,k,l; cin>>n>>m; while(m != 0) { if( m>1) { head=new node; head->d=1; head->next=NULL; r=head; for (i=2; i<=n; i++) { p=new node; p->d=i; p->next=NULL; r->next=p; r=p; } r->next=head; r = head; for (i=1; i<=n; i++) { for (j=1; j<=m-2; j++) r=r->next; r->next=r->next->next; r=r->next; } cout<<r->d<<endl; cin>>n>>m; } else { cout<<n<<endl; cin>>n>>m; } } return 0; }
原文地址:https://www.cnblogs.com/DukeLv/p/8321967.html