数据结构循环链表与双链表实验

来源:互联网 发布:禁毒网络知识登录竞赛 编辑:程序博客网 时间:2024/06/06 16:26
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#define OK 1
//#define ERROR -1
#define OVERFLOW -2
using namespace std;
//结构体
typedef int ElemType;
typedef int Status;
typedef struct LNode
{
    ElemType data;
    struct LNode* next;
}LNode,*LinkList;
typedef struct CNode
{
    char data;
    struct CNode* next;
}CNode,*CLinkList;
typedef struct DulNode
{
    ElemType data;
    struct DulNode* prior;
    struct DulNode* next;
}DulNode,*DuLinkList;
//函数声明:
Status InitList(LinkList &L);//初始化循环链表
Status InsertList(CLinkList &L,char e,int pos);
Status InitList(CLinkList &L);//重载初始化单链表
ElemType GetElem(LinkList &L,int i);//获取表L内第i个元素的值
Status InsertList(LinkList &L,ElemType e,int pos);//向表L中将元素e插入到第pos位
LinkList LocateElem(LinkList &L,ElemType e);//根据想要查找的元素值返回接收结点的地址值
bool isEmpty(LinkList &L);//判断链表是否为空
void ShowAllData(LinkList &L,int length);//显示所有元素
void ShowAllData(CLinkList &L,int length);//重载显示所有元素函数
void DeleteFormerNode(LinkList &L,ElemType e);//删除数据为e的结点的前驱结点
//函数区
int main()
{
    int ListLength = 0,length;//循环链表长度
    ElemType e;
    LinkList SCList;//建立循环链表
    InitList(SCList);//初始化循环链表
    cout<<"请输入循环链表长度:";
    cin>>length;
    if(length<=0)
    {
        cout<<"长度不能小于0,请重试。"<<endl;
        return 0;
    }
    LinkList p=SCList;
    for(int i = 0;i<length;i++)
    {
        LinkList q = new LNode;
        cin>>e;
        if(p->next == p)
        {
            p->data = e;
            p ->next = q;
            q->next = p;
        }
        else InsertList(SCList,e,i);
        ListLength++;
        p = p->next;
    }
    ShowAllData(SCList,ListLength);
    cout<<"请输入你要删除前驱结点的元素的值:";
    int value;
    cin>>value;
    DeleteFormerNode(SCList,value);
    ListLength = length = length - 1;
    ShowAllData(SCList,ListLength);


    CLinkList CList,A,B,C;
    InitList(CList);
    InitList(A);
    InitList(B);
    InitList(C);
    A->next = A;
    B->next = B;
    C->next = C;
    fflush(stdin);
    int CListLength=0;//缓冲区溢出问题,但是根本无法解决
    int ALength=0;
    int BLength=0;
    int CLength=0;
    cout<<"请输入您要存储的字符个数:";
    scanf("%d",&CListLength);
    cout<<"请输入您要存储的元素:";
    CLinkList s=CList;
    char str[100];
    for(int i = 0;i<CListLength;i++)
        {
            fflush(stdin);//缓冲区溢出问题
            scanf("%c",&str[i]);
            CLinkList t = new CNode;
            s->next = t;
            InsertList(CList,str[i],i );
                if(str[i]>='0'&&str[i]<='9')
                {
                    InsertList(A,str[i],ALength);
                    ALength++;
                }
                else if(str[i]>='a'&&str[i]<='z')
                {
                    InsertList(B,str[i],BLength);
                    BLength++;
                }
                else{
                    InsertList(C,str[i],CLength);
                    CLength++;
                }
            s = s->next;
        }
        s = CList;
//    ShowAllData(CList,CListLength);
    printf("表A中元素为:\n");
    ShowAllData(A,ALength);
    printf("表B中元素为:\n");
    ShowAllData(B,BLength);
    printf("表C中元素为:\n");
    ShowAllData(C,CLength);
    getchar();
    return 0;
}
void DeleteFormerNode(LinkList &L,ElemType e)//删除数据为e的结点的前驱结点
{
    LinkList p = L,s;
    s = new LNode;
    s->data = e;
    while((s->data) != (p->next->next->data) )
    {
         if(p->next == L)
         {
            cout<<"不存在该元素,删除失败"<<endl;
            return;
         }
         p=p->next;
    }
    s->next = p->next->next->next;
    p->next = s;


}


void ShowAllData(LinkList &L,int length)//显示所有元素函数
{
    int i = 0;
    LinkList p = L;
    while(i<length)
    {
        cout<<"第"<<i+1<<"个元素为:"<<p->data<<endl;
        p = p->next;
        i++;
    }
    return;
}
void ShowAllData(CLinkList &L,int length)//重载显示所有元素函数
{
    int i = 0;
    CLinkList p = L;
    p = p->next;
    while(i<length)
    {
        cout<<"第"<<i+1<<"个元素为:"<<p->data<<endl;
        p = p->next;
        i++;
    }
    return;
}


Status InsertList(LinkList &L,ElemType e,int pos)//向表L中将元素e插入到第pos位
{
    LinkList p = L,q;
    q = new LNode;
    int j = 0;
    while (p && j<pos-1 )
    {
        p = p->next;
        j++;
    }
    q->data = e;
    q->next = p->next;
    p->next = q;
    return OK;
}
Status InsertList(CLinkList &L,char e,int pos)//重写向表L中将元素e插入到第pos位
{
    CLinkList p = L,q;
    q = new CNode;
    int j = 0;
    while (p && j<pos)
    {
        p = p->next;
        j++;
    }
    q->data = e;
    q->next = p->next;
    p->next = q;
    return OK;
}
LinkList LocateElem(LinkList &L,ElemType e)//根据想要查找的元素值返回接收结点的地址值
{
    LinkList p = L->next;
    while(p)
    {
        if( (p->data) == e ) return p;
        else {
            p = p->next;
        }
    }
    return NULL;
}


ElemType GetElem(LinkList &L,int pos)//获取表L内第i个元素的值
{
    LinkList p = L->next;
    int j = 0;
    while(p&&j<pos)
    {
        p = p->next;
        j++;
    }
    return p->data;
}


Status InitList(LinkList &L)//初始化循环单链表
{
    L = new LNode;
    if(!L)return 0;
    L->next = L;
    return OK;
}
Status InitList(CLinkList &L)//重载初始化单链表
{
    L = new CNode;
    if(!L)exit(0);
    return OK;

}




双链表部分:


#include <iostream>
#include <stdio.h>
#include <malloc.h>
using namespace std;


typedef struct DNode
{
    int data;
    int freq;
    struct DNode *next;
    struct DNode *prior;
} DinkList;


DinkList *h;
void sort(DinkList *&h)//根据freq降序排列,写成一个函数
{
    DinkList *p,*q,*pre;
    p=h->next->next;
    h->next->next=NULL;
    while(p!=NULL)
    {
        q=p->next;
        pre=h;
        while(pre->next!=NULL&&(pre->next->freq)>(p->freq))//根据freq降序
            pre=pre->next;
        p->next=pre->next;
        if(pre->next!=NULL)
            pre->next->prior=p;
        pre->next=p;
        p->prior=pre;
        p=q;
    }
}


void LocateNode(DinkList *&h,int x)
{
    DinkList *p;
    p=h->next;
    int i=0;
    //查找x所在的位置
    while(p!=NULL&&p->data!=x)
    {
        p=p->next;
        ++i;
    }
    p->freq++;//x元素的freq++
    //sort(h);//下面是sort
    DinkList *q,*pre;
    p=h->next->next;//把p放在头结点的第二位
    h->next->next=NULL;//把第一位第二位节点断开
    while(p!=NULL)//遍历所有结点为止
    {
        q=p->next;//q在p之后
        pre=h;//pre存储头结点地址
        while(pre->next!=NULL&&pre->next->freq>p->freq)//如果链表没有到表尾并且第一个结点的频度大于第二个结点的频度 进入循环
            pre=pre->next;//pre后挪一位
        p->next=pre->next;//令p下一位链接的是pre的下一位
        if(pre->next!=NULL)
            pre->next->prior=p;
        pre->next=p;
        p->prior=pre;
        p=q;
    }
}
int main()
{
    DinkList *s;
    h=(DinkList *)malloc(sizeof(DinkList));
    int a[6];
    int i;
    for(i=0; i<6; i++)//初始化a数组
        a[i]=i+1;
    h->prior=h->next=NULL;
    for(i=0; i<6; i++)//头插法
    {
        s=(DinkList *)malloc(sizeof(DinkList));
        s->data=a[i];
        s->freq=0;
        s->next=h->next;
        if(h->next!=NULL)
            h->next->prior=s;
        h->next=s;
        s->prior=h;
    }
    DinkList *p;
    int temp;
    while(1)
    {
        printf("请输入要访问的元素");
        scanf("%d",&temp);
        LocateNode(h,temp);
        p=h->next;
        while(p!=NULL)
        {
            cout<<p->data<<" ";
            cout<<"freq="<<p->freq<<endl;


            p=p->next;
        }
        cout<<endl;
    }


    return 0;
}