一、作业
1.双向链表
主函数:
//创建双向链表
NodePtr list_creat()
{
//在堆区申请一个头结点
NodePtr L = (NodePtr)malloc(sizeof(Node));
if(NULL == L)
{
printf("创建失败\n");
return NULL;
}
//说明链表创建成功
L->len = 0;
L->prio = NULL;
L->next = NULL;
printf("创建成功\n");
return L;
}
//链表判空
int list_empty(NodePtr L)
{
return L->next == NULL;
}
//申请节点封装数据
NodePtr apply_node(datatype e)
{
//申请节点空间的大小
NodePtr p = (NodePtr)malloc(sizeof(Node));
if(NULL == p)
{
printf("申请失败\n");
return NULL;
}
//给节点赋值
p->data = e;
p->prio = NULL;
p->next = NULL;
}
//链表头插
int list_insert_head(NodePtr L,datatype e)
{
//判断逻辑
if(NULL == L)
{
printf("插入失败\n");
return -1;
}
//头插逻辑
NodePtr p = apply_node(e);
if(NULL == p)
{
return -1;
}
if(list_empty(L))
{
p->prio = L;
L->next = p;
}
else
{
p->prio = L;
p->next = L->next;
L->next->prio = p;
L->next = p;
}
printf("插入成功\n");
L->len++;
return 0;
}
//链表遍历
int list_show(NodePtr L)
{
//判断逻辑
if(NULL == L||list_empty(L))
{
printf("遍历失败\n");
return -1;
}
//遍历逻辑
NodePtr q = L->next;
while(q)
{
//输出数据域
printf("%c\t",q->data);
//遍历指针后移
q = q->next;
}
printf("\n");
return 0;
}
//按位置查找返回节点
NodePtr list_search_pos(NodePtr L,int pos)
{
//判断逻辑
if(NULL == L||list_empty(L)||pos<0||pos>L->len)
{
printf("查找失败\n");
return NULL;
}
//查找逻辑
NodePtr q = L;//从头结点出发
for(int i=0;i<pos;i++)
{
q = q->next;
}
//返回节点
return q;
}
//链表任意位置插入
int list_add_pos(NodePtr L,int pos,datatype e)
{
//判断逻辑
if(NULL == L||pos<0||pos>L->len)
{
printf("插入失败\n");
return -1;
}
//申请节点空间的大小
NodePtr q = apply_node(e);
if(NULL == q)
{
printf("操作失败\n");
return -1;
}
if(list_empty(L))
{
q->prio = L;
L->next = q;
}else
{
//查找到前一个节点的位置:
NodePtr p = list_search_pos(L,pos-1);
q->prio = p;
q->next = p->next;
p->next->prio = q;
p->next = q;
}
//表长变化
L->len++;
printf("插入成功\n");
return 0;
}
//查找链表某位置元素并输出
int list_search_output(NodePtr L,int pos)
{
NodePtr q = list_search_pos(L,pos);
printf("该位置元素信息为:%c\n",q->data);
return 0;
}
//链表任意位置删除
int list_delete_pos(NodePtr L,int pos)
{
//判断逻辑
if(NULL == L||list_empty(L)||pos<1||pos>L->len)
{
printf("删除失败\n");
return -1;
}
//找到要删除的节点
NodePtr p = list_search_pos(L,pos);
//删除逻辑
if(p->next == NULL)
{
//p为最后一个节点
p->prio->next = NULL;
}
else
{
p->next->prio = p->prio;
p->prio->next = p->next;
}
free(p);
p = NULL;
//表长变化
L->len--;
printf("删除成功\n");
return 0;
}
//修改链表指定位置内容
int list_xiugai(NodePtr L,int pos,datatype e)
{
//判断逻辑
if(NULL==L||list_empty(L))
{
printf("修改失败\n");
return -1;
}
//查找到要修改的位置节点
NodePtr p = list_search_pos(L,pos);
//修改逻辑
p->data = e;
printf("修改成功\n");
return 0;
}
//链表删除
void list_destory(NodePtr L)
{
//判断逻辑
if(NULL == L)
{
printf("删除失败\n");
return;
}
//删除所有节点
while(!list_empty(L))
{
list_delete_pos(L,1);
}
//删除头节点
free(L);
L = NULL;
printf("链表释放成功\n");
}
2.循环链表
//创建循环链表
NodePtr list_creat()
{
//在堆区申请一个头结点
NodePtr L = (NodePtr)malloc(sizeof(Node));
if(NULL == L)
{
printf("创建失败\n");
return NULL;
}
L->len = 0;
L->next = L;//头结点指针域指向自己
printf("创建成功\n");
return L;
}
//链表判空(辅助函数)
int list_empty(NodePtr L)
{
return L->next == L;
}
//链表申请空间封装节点(辅助函数)
NodePtr apply_node(datatype e)
{
//堆区申请一个节点的空间
NodePtr p = (NodePtr)malloc(sizeof(Node));
if(NULL == p)
{
printf("创建失败\n");
return NULL;
}
//给结点赋值
p->data = e;
p->next = NULL;
return p;
}
//辅助函数:按位置进行查找节点
NodePtr list_search_pos(NodePtr L,int pos)
{
if(NULL == L||pos<0||pos>L->len)
{
printf("查找失败\n");
return NULL;
}
NodePtr q = L;
for(int i=0;i<pos;i++)
{
q = q->next;
}
return q;
}
//尾插
int list_insert_tail(NodePtr L,datatype e)
{
//判断逻辑
if(NULL == L)
{
printf("插入失败\n");
return -1;
}
//找到最后一节点
NodePtr q = list_search_pos(L,L->len);
//封装节点
NodePtr p = apply_node(e);
if(NULL == p)
{
return -1;
}
//插入逻辑
p->next = q->next;
q->next = p;
//表的变化
L->len++;
printf("插入成功\n");
return 0;
}
//任意位置插入(增)
int list_add_pos(NodePtr L,int pos,datatype e)
{
//判断逻辑
if(NULL == L||pos<0||pos>L->len)
{
printf("插入失败\n");
return -1;
}
//封装节点
NodePtr p = apply_node(e);
if(list_empty(L))
{
p->next = L;
L->next = p;
}else
{
//找到前一个节点位置
NodePtr q = list_search_pos(L,pos);
//插入逻辑
p->next = q->next;
q->next = p;
}
//表长变化
L->len++;
printf("插入成功\n");
return 0;
}
//链表遍历
int list_show(NodePtr L)
{
//判断逻辑
if(NULL == L||list_empty(L))
{
printf("遍历失败\n");
return -1;
}
NodePtr q = L->next;
while(q!=L)
{
printf("%c\t",q->data);
q=q->next;
}
printf("\n");
return 0;
}
//链表头删
int list_delete_head(NodePtr L)
{
//判断逻辑
if(NULL == L||list_empty(L))
{
printf("删除失败\n");
return -1;
}
//头删逻辑
NodePtr q = L->next;
L->next = q->next;
free(q);
q = NULL;
//表长变化
L->len--;
printf("删除成功\n");
return 0;
}
//任意位置删除(删)
int list_delete_pos(NodePtr L,int pos)
{
//判断逻辑
if(NULL == L||list_empty(L)||pos<0||pos>L->len)
{
printf("删除失败\n");
return -1;
}
//查找节点位置
NodePtr q = list_search_pos(L,pos-1);
NodePtr p = q->next;
q->next = p->next;
free(p);
p == NULL;
L->len--;
printf("删除成功\n");
return 0;
}
//修改某位置元素
int list_xiugai(NodePtr L,int pos,datatype e)
{
//判断逻辑
if(NULL == L||list_empty(L)||pos<0||pos>L->len)
{
printf("删除失败\n");
return -1;
}
//修改逻辑
NodePtr q = list_search_pos(L,pos);
q->data = e;
printf("修改成功\n");
return 0;
}
//链表销毁
void list_destory(NodePtr L)
{
//判断逻辑
if(NULL == L)
{
printf("释放失败\n");
return;
}
//删除节点
while(!list_empty(L))
{
list_delete_head(L);
}
//释放头结点
free(L);
L=NULL;
printf("销毁成功\n");
return;
}
3.用循环链表解决约瑟夫环问题:
函数声明:
#ifndef YUE_H
#define YUE_H
#include<myhead.h>
typedef int datatype;//定义数据域
typedef struct Yue//定义一个结构体指针域
{
union
{
datatype data;//普通数据域
int len;//头结点
};
struct Yue *prio;//上一个指针域
struct Yue *next;//下一个指针域
}Yue, *YuePtr;
//创建一个循环链表
YuePtr yue_creat();
//封装节点
YuePtr apply_yue(datatype e);
//插入n个元素
int yue_insert(YuePtr Y);
//遍历查看这组数据的顺序
int yue_show(YuePtr Y);
//删除并输出遍历m次的元素
int yue_delete_output(YuePtr Y,int m);
#endif
2.源代码
#include"yue.h"
//创建一个循环链表
YuePtr yue_creat()
{
YuePtr Y = (YuePtr)malloc(sizeof(Yue));
if(NULL == Y)
{
printf("创建失败\n");
return NULL;
}
int len = len;
Y->next = Y;
Y->prio = Y;
printf("创建成功\n");
return Y;
}
//封装节点
YuePtr apply_yue(datatype e)
{
YuePtr p = (YuePtr)malloc(sizeof(Yue));
if(NULL == p)
{
printf("申请失败\n");
return NULL;
}
p->data = e;
p->prio = NULL;
p->next = NULL;
}
//插入n个元素
int yue_insert(YuePtr Y)
{
//判断逻辑
if(NULL == Y)
{
printf("插入失败\n");
return -1;
}
YuePtr q = Y;
printf("请输入参与约瑟夫环的数据个数:\n");
scanf("%d",&Y->len);
for(int i=0;i<Y->len;i++)
{
datatype e = 0;
printf("请输入第%d个数据:\n",i+1);
scanf("%d",&e);
YuePtr p = apply_yue(e);
if(Y->next==Y)
{
p->prio = Y;
p->next = Y;
Y->prio = p;
Y->next = p;
}else
{
p->next = Y->next;
p->prio = Y;
Y->next->prio = p;
Y->next = p;
}
}
return 0;
}
//输出n个数据的顺序
int yue_show(YuePtr Y)
{
//判断逻辑
if(NULL == Y||Y->next==Y)
{
printf("输出失败\n");
return -1;
}
printf("该组数据顺序为:\n");
YuePtr p = Y->next;
while(p!=Y)
{
printf("%d\t",p->data);
p = p->next;
}
printf("\n");
return 0;
}
//删除并输出遍历m次的元素
int yue_delete_output(YuePtr Y,int M)
{
if(Y->next==Y)
{
return 0;
}else
{
YuePtr p = Y;
for(int i=0;i<M;i++)
{
if(p->next!=Y)
{
p=p->next;
}else
{
p=Y->next;
}
}
printf("%d\t",p->data);
p->prio->next = p->next;
p->next->prio = p->prio;
free(p);
p=NULL;
Y->len--;
return yue_delete_output(Y,M);
}
}
3.主函数
#include<myhead.h>
#include"yue.h"
int main(int argc, const char *argv[])
{
int len = 0;//初始化一个参与数据个数
int M =0;
//创建一个可以包括一组约瑟夫环数据的循环链表
YuePtr Y = yue_creat();
if(NULL == Y)
{
printf("创建失败\n");
return -1;
}
yue_insert(Y);
yue_show(Y);
printf("请输入M:\n");
scanf("%d",&M);
yue_delete_output(Y,M);
printf("\n");
return 0;
}
运行结果:
4.进制转换
函数声明:
#ifndef CHANGE_H
#define CHANGE_H
#include<myhead.h>
#define MAX 100//最大容量
typedef int datatype;
typedef struct
{
datatype *data;
int top;
}Change,*ChangePtr;
//创建一个栈的空间
ChangePtr creat();
//入栈
int insert_2(ChangePtr C,int a);
int insert_8(ChangePtr C,int a);
int insert_16(ChangePtr C,int a);
//出栈
int pop(ChangePtr C);
int pop_16(ChangePtr C);
//销毁该栈区空间
//void destory(ChangePtr C);
#endif
源代码:
//创建函数
ChangePtr creat()
{
ChangePtr C = (ChangePtr)malloc(sizeof(Change));
if(NULL == C)
{
printf("创建失败\n");
return NULL;
}
C->data = (datatype *)malloc(sizeof(datatype)*MAX);
if(NULL == C->data)
{
printf("创建失败\n");
return NULL;
}
bzero(C->data,sizeof(datatype)*MAX);
C->top = -1;
printf("创建成功\n");
return C;
}
//判空
//C->top==-1
//判满
//C->top==MAX-1;
//入栈
int insert_2(ChangePtr C,int a)
{
while(a!=0)
{
C->top++;
C->data[C->top] = a%2;
a=a/2;
}
printf("入栈成功\n");
return 0;
}
int insert_8(ChangePtr C,int a)
{
while(a!=0)
{
C->top++;
C->data[C->top] = a%8;
a=a/8;
}
printf("入栈成功\n");
return 0;
}
int insert_16(ChangePtr C,int a)
{
while(a!=0)
{
C->top++;
C->data[C->top] = a%16;
a=a/16;
}
printf("入栈成功\n");
return 0;
}
//出栈
int pop(ChangePtr C)
{
if(C->top==-1)
{
return 0;
}else
{
printf("%d\t",C->data[C->top]);
C->top--;
return pop(C);
}
}
int pop_16(ChangePtr C)
{
if(C->top==-1)
{
return 0;
}else
{
printf("%x\t",C->data[C->top]);
C->top--;
return pop(C);
}
}
主函数:
#include"change.h"
#include<myhead.h>
int main(int argc, const char *argv[])
{
int a = 0;
int me_nu=0;
//调用创建函数
ChangePtr C = creat();
while(1)
{
printf("请输入转换为几进制:\n");
scanf("%d",&me_nu);
switch(me_nu)
{
case 1:
{
//转换为二进制
printf("请输入一个整数:\n");
scanf("%d",&a);
insert_2(C,a);
pop(C);
printf("\n");
}
break;
case 2:
{
//转换为八进制
printf("请输入一个整数:\n");
scanf("%d",&a);
insert_8(C,a);
pop(C);
printf("\n");
}
break;
case 3:
{
//转换为十六进制
printf("请输入一个整数:\n");
scanf("%d",&a);
insert_16(C,a);
pop_16(C);
printf("\n");
}
break;
case 0:
{
goto END;
}
dafult:
printf("您输入的内容有误,请重新输入\n");
}
}
END:
//调用销毁函数
return 0;
}