NeuSoft练习5

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

/*  链表节点结构体*/
typedef struct LinkNode
{
 int data;   //数据域
    struct LinkNode *next;//指向下一个节点的指针
}LinkNode;

/****************************************************************************/
//函数名:CreatLinkList
//创作日期:2007.6.24
//功能:创建链表

/****************************************************************************/

LinkNode *CreatLinkList()
{
 int i;
 LinkNode *L = NULL, *p = NULL, *pre = NULL;
 L = (LinkNode*)malloc(sizeof(LinkNode));
 L->next =NULL;
 p = L;
 pre = L;
 /* 采用尾差发依次插入节点*/
 for(i = 0; i < 10; i++)
 {
  p = (LinkNode*)malloc(sizeof(LinkNode));
  /* 节点的数据域取1000以内的随机数*/
  p->data = rand()%1000;

  /* 插入节点*/
  p->next = pre->next;
  pre->next = p;
  
  /* 更新前驱指针*/
  pre = p;
 }
 return L;
}
/****************************************************************************/
//函数名:PrintLink
//创作日期:2007.6.24
//功能:将链表打印输出

/****************************************************************************/

void PrintLink(LinkNode *L)
{
   LinkNode *p = L->next;
   printf("输出链表为:/n");
   while(p)
   {
    printf("%d  ", p->data);
    p = p->next;
   }
}
/****************************************************************************/
//函数名:DispartLinkList
//创作日期:2007.6.24
//功能:将链表进行拆分

/****************************************************************************/

void DispartLinkList(LinkNode *L, LinkNode *Queue[], int location, int divide)
{
 int i, choose;
 /*  p指向当前被拆下来的节点,ptr指向p的后继 */
 /*  pre[10]是一个指向前驱节点的指针数组*/
 LinkNode *p = NULL, *pre[10] = {NULL}, *ptr = NULL;

 assert( L != NULL);

 /*  p初始化为第一个节点  */
 p = L->next;
 /*  ptr与p的初始化相同  */
 ptr = p;

 for(i = 0; i < 10; i++)
 {
  /*  为指针数组Queue[i]分配头节点*/
  Queue[i] = (LinkNode *)malloc(sizeof(LinkNode));
  if( Queue[i] == NULL)
  {
   printf("malloc error!");
   exit(1);
  }
  /* 并分别用pre[i]指向个头节点 */
  pre[i] = Queue[i];
  pre[i]->next = NULL;
 }
 
 /* 如果当前拆分节点不为空的话*/
 while(p)
 {
  /* 保存当前节点的下一个节点 */
  ptr = p->next;
  /* 将当前指向的节点从链表中拆下*/
  L->next = p->next;

  if(location == 0)
  {
   choose = p->data / divide;
  }
  else if(divide == 0)
  {
   choose = p->data % location;
  }
  else
  {
   choose = p->data % location / divide;
  }
  switch(choose)
  {
   case 0:
    {
     /* 用尾差发将p指向的节点插入 */
     p->next = pre[0]->next;
     pre[0]->next = p;
        pre[0] = p;
     break;
    }
   case 1:
    {
     p->next = pre[1]->next;
     pre[1]->next = p;
     pre[1] = p;
     break;
    }
      case 2:
    {
     p->next = pre[2]->next;
     pre[2]->next = p;
        pre[2] = p;
     break;
    }
   case 3:
    {
     p->next = pre[3]->next;
     pre[3]->next = p;
        pre[3] = p;
     break;
    }
   case 4:
    {
     p->next = pre[4]->next;
     pre[4]->next = p;
        pre[4] = p;
     break;
    }
   case 5:
    {
     p->next = pre[5]->next;
     pre[5]->next = p;
        pre[5] = p;
     break;
    }
   case 6:
    {
     p->next = pre[6]->next;
     pre[6]->next = p;
        pre[6] = p;
     break;
    }
   case 7:
    {
     p->next = pre[7]->next;
     pre[7]->next = p;
        pre[7] = p;
     break;
    }
   case 8:
    {
     p->next = pre[8]->next;
     pre[8]->next = p;
        pre[8] = p;
     break;
    }
   case 9:
    {
     p->next = pre[9]->next;
     pre[9]->next = p;
        pre[9] = p;
     break;
    }
  }
  p = ptr;

 }
}

/****************************************************************************/
//函数名:PrintDispartLink
//创作日期:2007.6.24
//功能:打印被拆分的队列链表

/****************************************************************************/
void PrintDispartLink(LinkNode *Queue[])
{
 int i;
 printf("/n输出拆分的队列链表为/n");
 for(i = 0; i < 10; i++)
 {
  LinkNode *p = Queue[i];
  p = p->next;
  while(p)
  {
   printf("  %d", p->data);
   p = p->next;
  }
  printf("/n");
 }
}
/****************************************************************************/
//函数名:CollectLinkList
//创作日期:2007.6.24
//功能:将链表进行收集

/****************************************************************************/

LinkNode *CollectLinkList(LinkNode *Queue[])
{
 /*  p用于指向当前用于进行操作的节点*/
 /*  pre指向p的前驱,ptr指向p的后继*/
 LinkNode *p = NULL, *pre = NULL, *ptr = NULL;
 int i;
 /*  分配头节点*/
 LinkNode *L = (LinkNode*)malloc(sizeof(LinkNode));
 /*  头节点的next域必须初始化为NULL*/
 L->next = NULL;
 /*  分别对pre和ptr进行付值*/
 pre = L;
 ptr = L;

 for(i = 0; i < 10; i++)
 {
  /* 依将指针数组中的各个地址付给p*/
  p = Queue[i]->next;
  /* 如果p存在的话*/
  while(p)
  {
   /* 保存p的后继指针*/
   ptr = p->next;

   /* 将拆分链表的节点取下,放入单链表中*/
   p->next = pre->next;
   pre->next = p;

   /* 更新前驱指针*/
   pre = p;
   /* 更新后继指针*/
   p = ptr;
  }
 }
 /* 返回头指针*/
 return L;
}
/****************************************************************************/
//函数名:FreeLinkList
//创作日期:2007.6.24
//功能:释放单链表

/****************************************************************************/

void FreeLinkList(LinkNode *L)
{
 
 LinkNode *p = NULL, *ptr = NULL;
 assert(L != NULL);
 p = L;
 ptr = p;
 while(p)
 {
  /* 保存后继指针*/
  ptr = ptr->next;
  free(p);
  p = NULL;
  /* 更新当前指针*/
  p = ptr;
 }

}

void FreeDispartLinkList(LinkNode *Queue[],int n)
{
 int i;
 for(i = 0; i < n; i++)
 {
  free(Queue[i]);
  Queue[i] = NULL;
 }

}

int main()
{
 /* 定义一个指针数组*/
 LinkNode *QueueLink[10];
 /* 定义一个头节点用于指针的传递*/
 LinkNode *Head;
 
 /* 创建链表并打印输出链表*/
 Head = CreatLinkList();
 PrintLink(Head);


 /* 按十位拆分链表*/
 DispartLinkList(Head, QueueLink, 10, 0);
 /* 销毁刚才创建的单链表*/
 FreeLinkList(Head);
 /* 打印拆分后的链表*/
 PrintDispartLink(QueueLink);
 /* 收集链表重新生成一个单链表*/
 Head = CollectLinkList(QueueLink);
 /* 释放拆分链表的头节点*/
 FreeDispartLinkList(QueueLink, 10);
 /* 打印新生成的链表*/
 PrintLink(Head);


 
 /* 按十位拆分链表*/
 DispartLinkList(Head, QueueLink, 100, 10);
 /* 销毁刚才创建的单链表*/
 FreeLinkList(Head);
 /* 打印拆分后的链表*/
 PrintDispartLink(QueueLink);
 /* 收集链表重新生成一个单链表*/
 Head = CollectLinkList(QueueLink);
 /* 释放拆分链表的头节点*/
 FreeDispartLinkList(QueueLink, 10);
 /* 打印新生成的链表*/
 PrintLink(Head);

 /* 按百位拆分链表*/
 DispartLinkList(Head, QueueLink, 0, 100);
 /* 销毁刚才创建的单链表*/
 FreeLinkList(Head);
 PrintDispartLink(QueueLink);
 Head = CollectLinkList(QueueLink);
 /* 释放拆分链表的头节点*/
 FreeDispartLinkList(QueueLink, 10);
 PrintLink(Head);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值