#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);
}