前阵子因为复习期末考试博客好久不更,这阵子把我对数据结构这门课的实验代码贴上来,有对代码感兴趣或者不清楚的地方可以评论,我会一一解答。
1、假设在长度大于 1 的单循环链表中,既无头结点也无头指针。s 为指向某个结点的指针,试编写算法删除结点*s 的直接前驱结点。
2、已知由单链表表示的线性表中,含有三类字符的数据元素(如:字母、数字和其它字符),设计算法构造三个以循环链表示的线性表,使每一个表中只含同一类的字符,且利用原表中的结点空间作为这三个表的空间。(头结点可以另辟空间)
3、有一双链表,每个结点中除有 prior、data 和 next 域外,还有一访问频度域 freq,在链表被启用前,其值均初始化为零。每当在链表上进行一次 LOCATE(L,x)运算,元素值为 x 的结点中 freq 域的值增 1,并使此链表中结点保持按 freq 递减的顺序排列,以便使频繁访问的结点总是靠近表头。设计满足上述要求的 LOCATE算法。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#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);
//题目2:
CLinkList CList,A,B,C;
InitList(CList);
InitList(A);
InitList(B);
InitList(C);
int CLength;
cout<<"请输入您要存储的字符个数:";
cin>>CLength;
cout<<"请输入您要存储的元素:";
CLinkList s=CList;
char* ch;
//for(int i = 0;i<CLength;i++)
{
// CLinkList r = new CNode;
fflush(stdin);
scanf("%s",&ch);
cout<<ch;
}
CLinkList pa=A,pb=B,pc=C;
for(int i = 0;i<CLength;i++)
{
if (ch[i]>='a' && ch[i]<='z')
{
pa->data = ch[i];
pa = pa->next;
continue;
}
else if (ch[i]>='0' && ch[i]<='9')
{
pb->data = ch[i];
pb = pb->next;
continue;
}
else
{
pc->data = ch[i];
pc = pc->next;
continue;
}
}
ShowAllData(CList,CLength);
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;
while(i<length)
{
cout<<"第"<<i+1<<"个元素为:"<<p->data<<endl;
p = p->next;
i++;
}
return;
}
//bool isEmpty(LinkList &L)
//{
// LinkList p = L;
// if( ((p->next) == p) && (p->data == NULL) )
// {
// cout<<"true";
// return true;
// }
// else
// {
// return false;
// }
//}
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-1 )
{
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;
}
本文展示了如何在单循环链表中删除指定结点的前驱结点,以及如何将不同类型的字符分离到各自的循环链表中。此外,还提供了用于维护按访问频率递减排列的双链表的LOCATE算法实现。

1万+

被折叠的 条评论
为什么被折叠?



