数据机构-四种链表

来源:互联网 发布:淘宝买药可靠吗 编辑:程序博客网 时间:2024/05/16 18:27

单链表


#include <stdio.h>#include <math.h>#include <malloc.h>   //不要丢掉#include <string.h>#include <conio.h>#define NULL0typedefstruct student{    int data;    struct student * next;} node;//----------------------------------------------node* creat(int n) //1     node *head = NULL, *p = NULL, *s = NULL;    int x;    head = (node*)malloc(sizeof(node));    p = head;    for (int i = 1; i <= n; i++) //用一个n次循环来处理    {        printf("第%d个数据是:", i);        scanf("%d;", &x);        s = (node *)malloc(sizeof(node));        s->next = NULL;        s->data = x;        p->next = s;        p = s;    }    return (head);}//----------------------------------------------int ListEmpty(node* h) //返回1说明是空的{    return (h->next == NULL);}//--------------------------------------------void Display(node *h){    node *p = h->next;    if (p == NULL)    {        printf("List isempty");        return;    }    while (p != NULL) //这里比较的不是p->next;    {        //每个元素都可以处理到,循环n次处理n个元素        printf("%d   ", p->data);        p = p->next;    }    printf("\n");}//------------------------------------------------int Length(node *h){    node *p = h;    int i = 0; //i是用来记录循环次数的    while (p->next)    {        i++;        p = p->next;    }    return i;}//------------------------------void GetElem(node* h, int i, int &e) // 找到单链表h中第i个元素{    node *p = h;    int j = 0;    if (p == NULL)    {        printf("List isempty");        return;    }    while ((j < i) && p->next)    {        j++;        p = p->next;    }    if (p->next == NULL)    {        printf("没有第%d个元素\n", i);    }    else    {        e = p->data;        printf("第%d个元素为:%d\n", i, e);    }}//-----------------------------------------------void LocateElem(node *h, int e)   // 寻找给定元素在表中的位置标号{    node *p = h->next;    int i = 1; //跟p不配套了    if (p == NULL)    {        printf("List isempty");        return;    }    while (p && (p->data != e))    {        p = p->next;    //此时i跟p是配套的        i++;    }    if (p == NULL)    {        printf("没有第%d这个元素\n", e);    }    else    {        printf("%d在链表的第%d个位置\n", e, i);    }}int Insert(node* &h, inti, int e) // 在第i个元素前插入一个元素{    node* p = h;    node* s;    int j = 0;    while ((j < i - 1) && p) //选择p是为了能在最后一个元素后插入元素    {        j++;        p = p->next;    }    if (p == NULL)    {        printf("i范围错误");        return 0;    }    else    {        s = (node*)malloc(sizeof(node));        s->next = p->next;        s->data = e;        p->next = s;        return 1;    }}int Del(node*&h, inti) // 删除第i个元素{    //要删除一个节点,p是不可能走到最后一个节点的。    int j   = 0;    node* p = h;    node*q  = NULL;    if (p->next == NULL)    {        //printf("List isempty");        return 0;    }    while ((j < i - 1) && p->next)    {        j++;        p = p->next;    }    if (p->next == NULL)    {        //printf("i超出范围");        return 0;    }    else    {        q = p->next;    //q=0        p->next = q->next;    //q=0->next        free(q);        return 1;    }}void destroy(node*&h)     // 释放链表{    node*p = h;    node*q = p->next;    while (q != NULL)    {        free(p);        p = q;        q = q->next;    }    free(p);}void reverse(node*&h){    node*q1 = h->next,;    node*q2 = q1->next;    node*temp;    q1->next = NULL;    while (q2)  //至少有两个元素才好反转    {        temp = q2->next;        q2->next = q1;        q1 = q2;        q2 = temp;    }    h->next = q1; //q1指向最后一个节点}node* bubble_sort(node*&h, int size) //因为链表是单向的,所以选择下沉石头{    int i, j, temp;    node*p = h->next;    for (j = size - 1; j >= 1; j--)    {        p = h->next;        for (i = 0; i + 1 <= j; i++)        {            if (p->next->data < p->data)            {                temp = p->next->data;                p->next->data = p->data;                p->data = temp;            }            p = p->next;        }    }    return h;}










 

双链表

typedefstruct DNode

{

    int data;

    struct DNode *prior;

    struct DNode *next;

}node;

 

voidInit(node *&h)

{

    h=(node*)malloc(sizeof(node));

    h->prior=h->next=0;

}

 

 

插入节点

intInsert(node *&h,int i,int e)

{

    int j=0;

    node*p=h;

    node*s=null;

    while(p&&j<i-1)

    {

        j++;

        p=p->next;

    }

    if(p==null)

    {

        printf("为找到第%d个节点\n",i-1);//未找到地i-1个节点

        return 0;

    }

    else

    {

        s=(node*)malloc(sizeof(node));

        s->data=e;

              if(p->next!= NULL) p->next->prior=s;//如果是要在最后一个元素后面插入这句话就可以省掉

              s->prior=p;

              s->next=p->next;

              p->next=s;

              return 1;

    }

}

 

删除节点

intDeleteElem(node*&h,int i)//要删除一个节点,p是不可能走到最后一个节点的。

{

    int j=0;

    node*p=h;

    node*q=null;

    while(j<i-1&&p->next)

    {

        j++;

        p=p->next;

    }

    if(p->next==null)

    {

        printf("找到地%d个节点\n",i-1);//未找到地i-1的节点,如果要删除节点的前一个节点是最后一个节点的话

        return 0;

    }

    else

    {

        q=p->next;//q指向要删除的节点

        p->next=q->next;//0

        if(p->next != null)//如果删除的是最后一个节点

                p->next->prior=p;

        free(q);

        return 1;

    }

}

 

 

循环单链表

typedefstruct LNode

{

    char data;

    struct LNode *next;

}node;

 

voidInit(node*&h)

{

    h=(node*)malloc(sizeof(node));

    h->next=h;

}

 

voidDestroy(node*&h)    //引起注意

{

    node*p=h;

    node*q=p->next;

    while(q!=h)//注意这里和单链表不一样

    {

        free(p);

        p=q;

        q=p->next;

    }

    free(p);

}

 

voidEmpty(node *h)

{

    if(h->next==h)

        printf("list is empty!\n");

    else

        printf("list is notempty\n");

}

 

voidLength(node*h)

{

    node*p=h->next;

    int i=0;

    while(p!=h)

    {

        i++;

        p=p->next;

    }

    printf("length is %d\n",i);

}

 

voidDisplay(node*h)

{

    node*p=h->next;

    if(null==h)

        printf("list is empty!\n");

    while(p!=h)

    {

        printf("%c   ",p->data);

        p=p->next;

    }

}

 

voidGetElem(node*h,int i)

{

    int j=0;

    node*p=null;

    if(h->next!=null)

        printf("list is empty\n");

    p=h->next;

    while(p!=h)

    {

        j++;

        p=p->next;

    }

    if(h==p)

        printf("cant get theelem!\n");

    else

    {

        printf("the elemis%c\n",p->data);

    }

   

}

 

voidLocate(node*h,char e)

{

    node*p=h->next;

    int i=0;

    while(p!=h && p->data!=e)

    {

        p=p->next;

        i++;

    }

    if(p==h)

        printf("cant do it !\n");

    else

        printf("the number of %c is%d\n",e,i);

}

插入

voidInsert(node*h,int i,char e)//插入节点就两句话

{

    int j=0;

    node*p=h;

    node*s=null;

    while(p!=h&&j<i-1)

    {

        j++;

        p=p->next;

    }

    if(p==h)

    {

        printf("未找到第%d个节点\n",i-1);//未找到地i-1个节点

    }

    else

    {

        s=(node*)malloc(sizeof(node));

        s->data=e;

        s->next=p->next;//1

        p->next=s;//2

    }

}

删除

void del(node*&h,int i)

{

    int j=0;

    node*p=h;

    node *q=null;

       if(p->next==null)

              {

                     printf("List isempty");

                     return 0;

              }    if

    while(j<i-1&&p->next!=h)

    {

        j++;

        p=p->next;

    }

    if(p->next==h)

    {

        printf("未找到地%d个节点\n",i-1);

    }

    else

    {

        q=p->next;//q指向要删除的节点

        p->next=q->next;//0

        free(q);

    }

}

 

//栈是一个简单的链表,只有push(),pop(),top(),display()几个操作

#include<stdio.h>

#include<malloc.h>

#define NULL0

typedef struct stack

{

      int data;

      struct stack *next;   

}node;

 

voidInitStack(node* &h)

{

     h=(node*)malloc(sizeof(node));

     h->next=NULL;

}

栈长(跟链表一样)

intLength(node* h)

{

       int i=0;

       node* p=h;

       while(p->next)

       {

              i++;

             p=p->next;

       }

       //printf("链表的长度为%d\n",i);

       return i;

}

Push

void Push(node* &h,int e)//实际上就是在第一个节点前插入数据

{                    //处理h后的一个节点

       node* s;

       s=(node*)malloc(sizeof(node));

       s->data=e;

       s->next=h->next;

       h->next=s;

}

Pop

intpop(node* &h)//实际上就是删除第一个节点

{             //处理h后的一个节点

       node* p=h;

       int e;

       if(p->next==0)

              {

                     printf("Stack isempty!\n");

                     return 0;

              }

       p=p->next;//指向第一个节点

       //e=p->data;

       h->next=p->next;

       free(p);

       //printf("弹出的元素是:%d\n",e);

       return 1;

}

Top

intTop(node*h)//实际上就是读取第一个数据

{

       node*p=h;

       int e;

       if(p->next==NULL)

              {

                     printf("Stack isempty");

                     return 0;

              }

       e=p->next->data;

       printf("顶点的数为%d\n",e);

       return e;

}

打印(跟链表一样)

voiddispaly(node* h)

{

       node *p=h->next;

       if(p==NULL)

              {

                     printf("Stack isempty!\n");

                     return;

              }

       while(p!=NULL)//这里比较的不是p->next;

       {     //每个元素都可以处理到,循环n次处理n个元素

              printf("%d   ",p->data);

              p=p->next;

       }

       printf("\n");

}

 

voiddestroy(node*&h)     // 释放链表

{

       node*p=h;

       node*q=p->next;

       while(q!=NULL)

       {

              free(p);

              p=q;

              q=q->next;

       }

       free(p);

}

 

 

 

/*

队列

//队列,就是enqueue(),front(),dequeue(),display()一些函数

//用链表来表示

 

#include<stdio.h>

#include<malloc.h>

#define NULL0

 

typedefstruct student

{

       int data;

       struct student *next;

}node;

 

typedef struct linkqueue

{

       node*front;

       node*rear;

}queue;

 

 

void Init(queue*&q)

{

       q=(queue*)malloc(sizeof(queue));

       q->front=q->rear=NULL;

}

测长

int Length(queue*h)

{

       inti=0;

       node*p=h->front;//赋值有少许变化,把第一个元素的地址发给了p

       while(p)        //pi不同步了

       {

              i++;

              p=p->next;

       }

       returni;

}

 

int Empty(queue*h)

{

       if(h->rear==NULL)

              return 1;

       else

              return 0;

}

入队

queue*enQueue(queue *&h,inte)//想象成人们在排队

{

       node *s;

       s=(node*)malloc(sizeof(node));

       s->data=e;

       s->next=NULL;//插入一个元素,排在最后,从后面插入

       if(h->rear==NULL)//若队列为空

              h->front=h->rear=s;

       else

       {

        node *b=h->rear;

              b->next=s;//h->rear->next=s;

              h->rear=s;

              }

       return h;

}

出队

intdeQueue(queue *&h)

{

       node *t;

       if(h->rear==NULL)

              {

                     printf("Queue isempty!");

                     return 0;

        }

       if(h->front==h->rear)//队列中只有一个节点时

              {

                     t=h->front;

                     h->front=h->rear=NULL;

              }

       else

              {

                     t=h->front;

                     h->front=t->next;

              }

       free(t);

       return 1;

}

 

void Clear(queue*&h)

{

       node *p=h->front;//p指向第一个节点

       node *r=NULL;

       if(p)

              {

                     r=p->next;

                     while(r!=NULL)

                     {

                            free(p);

                            p=r;

                            r=p->next;

                     }

              }

       free(h);

}

打印

voiddisplay(queue *h)

{

       node* p=h->front;//p指向第一个节点

       if(h->rear==NULL)

          printf("Queue is empyt!\n");

       while(p)

       {

              printf("%d   ",p->data);

              p=p->next;

       }

       printf("\n");

}

约瑟夫问题(猴子选大王)

循环链表C语言实现

Slyar2009.3.31

http://www.slyar.com

*/

 

#include<stdio.h>

#include<stdlib.h>

 

/* 定义链表节点类型 */

typedefstruct node

{

    int data;

    struct node *next;

}linklist;

 

int main()

{

    int i, n, k, m, total;

    linklist *head, *p, *s, *q;

    /* 读入问题条件 */

    printf("请输入猴子的个数:");

    scanf("%d", &n);

    printf("请输入要从第几个猴子开始报数:");

    scanf("%d", &k);

    printf("请输入出局数字:");

    scanf("%d", &m);

    /* 创建循环链表,头节点也存信息 */

    head = (linklist*)malloc(sizeof(linklist));

    p = head;

    p->data = 1;

    p->next = p;

    /* 初始化循环链表 */

    for (i = 2; i <= n; i++)

    {

        s = (linklist*)malloc(sizeof(linklist));

        s->data = i;

        s->next = p->next;

        p->next = s;

        p = p->next;

    }

    /* 找到第 k 个节点 */

    p =head;

    for (i = 1; i < k; i++)

    {

        p = p->next;

    }

    /* 保存节点总数 */

    total = n;

    printf("\n出局序列为:");

    q = head;

    /* 只剩一个节点时停止循环 */

    while (total != 1)

    {

        /* 报数过程,p指向要删除的节点 */

        for (i = 1; i < m; i++)

        {

            p = p->next;

        }

        /* 打印要删除的节点序号 */

        printf("[%d] ", p->data);

        /* q 指向 p 节点的前驱 */

        while (q->next != p)

        {

            q = q->next;

        }

        /* 删除 p 节点 */

        q->next = p->next;

        /* 保存被删除节点指针 */

        s = p;

        /* p 指向被删除节点的后继 */

        p = p->next;

        /* 释放被删除的节点 */

        free(s);

        /* 节点个数减一 */

        total--;

    }

    /* 打印最后剩下的节点序号 */

    printf("\n\n猴子大王为第 [%d] 号\n\n", p->data);

    free(p);

    //system("pause");

    return 0;

}