欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

C语言双层链表

程序员文章站 2023-02-02 08:43:48
自学完c也有20来天了,最近都在学c++,今天在c++中偶然间看到了链表,就心血来潮想着自己写个双层链表,检验下c的链表学得怎么样,写完就迫不及待传到博客上了。要说csdn博客真是个好东西,互相分享...

自学完c也有20来天了,最近都在学c++,今天在c++中偶然间看到了链表,就心血来潮想着自己写个双层链表,检验下c的链表学得怎么样,写完就迫不及待传到博客上了。要说csdn博客真是个好东西,互相分享心得,笔记,互相学习,还方便自己以后查阅。

双层链表:链表的每一个节点中都存放着一个链表。

#include"double node.h"
#include
#include
#include
#include
using namespace std;

//头文件#include"double node.h"中的代码如下:
struct smallnode   //内层链表  
{
	int num;     //编号
	int data;    //存放的数据
	struct smallnode *pnext;//指向下一个内层链表节点
};
typedef struct smallnode smallnode;


struct bignode    //外层链表  每个节点中存有一个内层链表
{
	int num;    //编号
	struct smallnode *pheadsmall; //指向内层链表的头节点
	struct bignode *pnext;        //指向下一个外层链表节点
};
typedef struct bignode  bignode;


void main()
{
	array array = { 0,1,2,3,4,5,6,7,8,9 };
	bignode *pheadbnode;   //存储外层链表头节点
	bignode *pbnode;       //存储开辟内存后的节点地址
	smallnode *psnode; 	   //存储开辟内存后的节点地址
	bignode *pbtemp;       //副本存储上一节点地址
	smallnode *pstemp;     //副本存储上一节点地址

/**********************************************为外层头节点开辟内存**********************************************/

	pbnode = (bignode *)malloc(sizeof(bignode));  //为外层链表头节点分配内存
	pbtemp = pbnode;   //记录地址 用于改变下一节点指针指向
	pbnode->num = 0;
	pbnode->pnext = null;
	psnode = (smallnode *)malloc(sizeof(smallnode)); //为内层链表头节点分配内存
	pbnode->pheadsmall = psnode;   //存储内层链表头节点
	pheadbnode = pbnode;           //记录头节点 用于打印数据
	pstemp = psnode;               //记录地址
	psnode->num = 0;
	psnode->data = array[0];
	psnode->pnext = null;
	for (int j = 1; j < 10; j++)
	{
		psnode = (smallnode *)malloc(sizeof(smallnode));   //为内层链表节点分配内存
		pstemp->pnext = psnode;   //前面已经赋值pstemp = psnode;   这里就是给上一节点的pnext赋值 指向当前分配的节点地址
		pstemp = psnode;          //改变副本存储的地址
		psnode->num = j;
		psnode->data = array[j];
		psnode->pnext = null;
	}
/**********************************************为其余外层节点开辟内存**********************************************/

	for (int i = 1; i < 10; i++)
	{
		pbnode = (bignode *)malloc(sizeof(bignode));     //为外层链表节点分配内存
		pbtemp->pnext = pbnode;
		pbtemp = pbnode;   //改变副本存储的地址
		pbnode->num = i;
		pbnode->pnext = null;
		psnode = (smallnode *)malloc(sizeof(smallnode));//为内层链表节点分配内存
		pbnode->pheadsmall = psnode;  //存储内层链表头节点
		pstemp = psnode;   //记录地址
		psnode->num = 0;
		psnode->data = array[0];
		psnode->pnext = null;
		for (int k = 1; k < 10; k++)
		{
			psnode = (smallnode *)malloc(sizeof(smallnode));//为内层链表节点分配内存
			pstemp->pnext = psnode;
			pstemp = psnode;   //改变副本存储的地址
			psnode->num = k;
			psnode->data = array[k];
			psnode->pnext = null;
		}
	}

/**********************************************打印链表数据 验证正确与否**********************************************/

	for (int h = 0; h < 10; h++)
	{
		psnode = pheadbnode->pheadsmall;  //指向内层链表头节点
		cout << "当前外层节点地址: " << pheadbnode << "    " << "下一外层节点地址: " << pheadbnode->pnext << "    " << "当前外层节点编号: " << pheadbnode->num << endl;
		cout << "\n";
		for (int g = 0; g < 10; g++)
		{
			cout << "当前内层节点地址: " << psnode << "    " << "下一内层节点地址: " << psnode->pnext << "    " << "当前内层节点存储的数据: " << psnode->data << endl;
			psnode = psnode->pnext;
		}
		cout << "\n\n\n";
		pheadbnode = pheadbnode->pnext;    //指向下一外层节点
	}


	cin.get();
	//system("pause");	
}
//这里解释下为什么要把外层头节点和外层其余节点分开写:
//******************************头节点中,是这样的******************************
//pbnode = (bignode *)malloc(sizeof(bignode));  //为外层链表头节点分配内存     
//pbtemp = pbnode;  //记录地址 用于改变下一节点指针指向                        1
//pbnode->num = 0;                                                             2
//pbnode->pnext = null;                                                        3
//psnode = (smallnode *)malloc(sizeof(smallnode));//为内层链表头节点分配内存   4
//pbnode->pheadsmall = psnode;  //存储内层链表头节点                           5
//pheadbnode = pbnode;    //记录头节点 用于打印数据                            6
//pstemp = psnode;   //记录地址                                                7
//psnode->num = 0;                                                             8   
//psnode->data = array[0]; 
//psnode->pnext = null;

//*********************************其余节点,是这样的********************************
//for (int i = 1; i < 10; i++)
//{
//	pbnode = (bignode *)malloc(sizeof(bignode));  //为外层链表节点分配内存
//	pbtemp->pnext = pbnode;                                                    11
//	pbtemp = pbnode;   //改变副本存储的地址                                    12 
//	pbnode->num = i;                                                            13
//	pbnode->pnext = null;                                                      14
//	psnode = (smallnode *)malloc(sizeof(smallnode));//为内层链表节点分配内存   15
//	pbnode->pheadsmall = psnode;  //存储内层链表头节点                         16
//	pstemp = psnode;   //记录地址                                              17
//	psnode->num = 0;                                                           18
//	psnode->data = array[0];
//	psnode->pnext = null;
//细微的差别就在于外层头节点前面没有节点,所以标号2处   只是记录当前外层节点的地址   
//而其余外层节点之前都有节点  所以标号12,13处  先给上一外层节点的pnext赋值  再改变pbtemp的指向
//标号6处是为了后面方便打印链表  存储头节点用的  可以无视
//同理也要把内层头节点和内层其余节点分开写