鱼C论坛

 找回密码
 立即注册
查看: 2773|回复: 3

[技术交流] 单循环链表的另一种实现方式【虽然不如教材的经典,希望大家帮挑下缺点】

[复制链接]
发表于 2015-4-19 13:43:24 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>

typedef struct circularlinklist{
//数据域
int data;
//指针域
struct circularlinklist *pNext;
} CirLinkList,*pCirLinkList;

//创建一个空的循环链表
pCirLinkList CreateEmptyCircularLinkList(void);

//判断循环链表是否为空
_Bool is_empty(pCirLinkList pnode);

//获取相对于pnode节点偏移i个节点的地址,i必须满足条件:i>=0
pCirLinkList GetNodeAddress(pCirLinkList pnode, int i);

//在相对于pnode节点偏移i个节点的后面插入1个节点,i必须满足条件:i>=0
void InsertNode(pCirLinkList pnode, int i);

//在相对于pnode节点偏移i个节点的后面插入n个节点,必须满足条件:i>=0 && n>=0
void InsertnNode(pCirLinkList pnode, int i, int n);

//统计循环链表的当前节点总数并返回计数值
int NodeSumCount(pCirLinkList pnode);

//返回相对于pnode节点偏移i个节点中的数据域,必须满足条件:i>=0
int GetNodeData(pCirLinkList pnode, int i);

//往节点中填充随机数据
void InputData(pCirLinkList pnode);

//函数功能:删除相对于pnode节点偏移的第i个节点,必须满足条件:i>=1
//如果为空循环链表,则无视后2个参数,等效于销毁操作,销毁完成后将*ppnode置为NULL
//如果pnode指向将要被删除的节点,则删除完成后,该函数会将*ppnode置为被删除节点的下一个节点的地址
//如果pnode没有指向要删除的节点,则删除完成后,该函数不会改变*ppnode中的值
void DeleteNode(pCirLinkList pnode, pCirLinkList *ppnode, int i);

//函数功能:删除相对于pnode节点偏移的第i个节点后的n个节点(包括第i个节点在内)
//如果为空循环链表,则无视后3个参数,等效于销毁操作,销毁完成后将*ppnode置为NULL
//如果i>=1&&i<=节点总数-1,则必须满足条件:i>=1+节点总数*m && i<=节点总数-1+节点总数*m && n>=1 && n<=节点总数-i(其中 m=0,1,2...)
//如果i>节点总数-1,则必须满足条件:i>=1+节点总数*m && i<=节点总数-1+节点总数*m && n>=1 && n<=节点总数-(i-节点总数*t)(其中 t满足i=k+节点总数*t,k>=1&&k<=节点总数-1)
void DeletenNode(pCirLinkList pnode, pCirLinkList *ppnode, int i, int n);

int main(void)
{
    pCirLinkList pnode = CreateEmptyCircularLinkList();

InsertnNode(pnode, 0, 9);
InputData(pnode);
for (int i = 0; i <= 9; i++)
{
  printf("%4d\t", GetNodeData(pnode, i));
}
DeletenNode(pnode, &pnode, 3, 7);
printf("\n\n");
for (int i = 0; i <= 9; i++)
{
  printf("%4d\t", GetNodeData(pnode, i));
}
printf("\n\n");
printf("当前节点总数=%d\n", NodeSumCount(pnode));
system("pause");
return 0;
}
pCirLinkList CreateEmptyCircularLinkList(void)
{
pCirLinkList pnode = (pCirLinkList)malloc(sizeof(CirLinkList));
pnode->pNext = pnode;//使节点的pNext指针指向该节点本身
return pnode;
}
_Bool is_empty(pCirLinkList pnode)
{
if (pnode == pnode->pNext)
{
  return true;
}
else
{
  return false;
}
}
pCirLinkList GetNodeAddress(pCirLinkList pnode, int i)
{
if (i < 0)
{
  return NULL;
}
for (int j = 1; j <= i; j++)
{
  pnode = pnode->pNext;
}
return pnode;
}
void InsertNode(pCirLinkList pnode, int i)
{
if (i < 0)
{
  return;
}
pCirLinkList pfront = GetNodeAddress(pnode, i);
pCirLinkList pback = GetNodeAddress(pnode, i + 1);
pfront->pNext = (pCirLinkList)malloc(sizeof(CirLinkList));
pfront->pNext->pNext = pback;
return;
}
void InsertnNode(pCirLinkList pnode, int i, int n)
{
if (i < 0 || n < 0)
{
  return;
}
for (int j = i; j <= i + n - 1; j++)
{
  InsertNode(pnode, j);
}
return;
}
int NodeSumCount(pCirLinkList pnode)
{
int i = 0;
while (i == 0 || GetNodeAddress(pnode, i) != pnode)
{
  i++;
}
return i;
}
int GetNodeData(pCirLinkList pnode, int i)
{
if (i < 0)
{
  return -32767;
}
return GetNodeAddress(pnode, i)->data;
}
void InputData(pCirLinkList pnode)
{
int len = NodeSumCount(pnode), i;
srand(time(NULL));
for (i = 0; i <= len - 1; i++)
{
  GetNodeAddress(pnode, i)->data=rand()%90+10;
}
return;
}
void DeleteNode(pCirLinkList pnode, pCirLinkList *ppnode, int i)
{
if (is_empty(pnode))//如果为空表,则等效于销毁操作
{
  free(GetNodeAddress(pnode, 0));
  *ppnode = NULL;
  return;
}
if (i < 1)
{
  return;
}
pCirLinkList pfront = GetNodeAddress(pnode, i - 1);
pCirLinkList pback = GetNodeAddress(pnode, i + 1);
pCirLinkList pmiddle = GetNodeAddress(pnode, i);
free(GetNodeAddress(pnode, i));
pfront->pNext = pback;
if (pnode == pmiddle)//pnode指向被删除的节点的情况
{
  *ppnode = pback;
}
return;
}
void DeletenNode(pCirLinkList pnode, pCirLinkList *ppnode, int i, int n)
{
int k, m;
int sum = NodeSumCount(pnode);
if (is_empty(pnode))//如果为空表,则等效于销毁操作
{
  DeleteNode(pnode, ppnode, 0);
  return;
}
for (k = 1; k <= sum - 1; k++)//检测i是否等于k+节点总数*m
{
  if ((i - k) % sum == 0 && i >= 1)
  {
   m = (i - k) / sum;//存储整数倍率
   break;
  }
}
if (k == sum)//如果k==sum,说明i!=k+节点总数*m || i<1
{
  return;
}
if (i >= 1 && i <= sum - 1)
{
  if (n<1 || n>NodeSumCount(pnode) - i)
  {
   return;
  }
}
else if (i > sum - 1)
{
  if (n<1 || n>NodeSumCount(pnode) - (i - sum*m))
  {
   return;
  }
}
for (int j = i + n - 1; j >= i; j--)
{
  DeleteNode(pnode, ppnode, j);
}
return;
}

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-5-26 01:27:06 | 显示全部楼层
支持
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-5-27 05:23:00 | 显示全部楼层
就是来顶 支持
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-27 12:19:04 | 显示全部楼层
楼主注意 下 格式 这样 可以看得更清楚点啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-12 20:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表