指针与结构(构建链接表) 指针系列之四
指针与结构(构建链接表)
指针系列之四
建立一个简单数据结构如下:(VC++6。0环境下)
struct listrec {
int value; //int变量
CString str; //字符串变量
struct listrec *next; //结构指针变量 指向一个和本结构一样的结构指针
};
如何利用上述结构来构造一个链接表呢?当节点不多只有几个是你可以如下进行构造:
构造一个5个节点的链接表
listrec x1,x2,x3,x4,x5,aa; //现定义5个节点及随后要插入进链表的节点aa
下面初始化5个节点如下
x1.value=111111;
x1.str="aaaaaa";
x1.next=&x2;
x2.value=222222;
x2.str="bbbbbb";
x2.next=&x3;
x3.value=333333;
x3.str="cccccc";
x3.next=&x4;
x4.value=444444;
x4.str="dddddd";
x4.next=&x5;
x5.value=555555;
x5.str="eeeeee";
x5.next=(struct listrec *)NULL;
第5个节点无下级节点,初始化为空;
链表建立后如何操作呢?比如删除和插入节点英国如何作?
*删除节点(以删除第3个节点为例)
x2.next=&x4;
这样x3节点就从该链接表中踢了出去
或者x2.next=(x2.next)->next
因为(x2.next)->next即为x3.next=&x4
*插入节点(在第3个节点后插入aa节点为例)
aa.next=x3.next; //第四个节点将位于aa节点之后
x3.next=&aa; // aa节点将位于第三个节点之后
如何动态分配内存空间建立链接表呢?
下面是一个动态分配内存建立有10个节点的链接表的例子
int i=0;
for(i=0;i<10;i++)
{
if(i==0) // 如果是第一个节点
{
ptmp=new listrec; //申请内存空间,取得分配成功后指向该节点的指针
Pnew=ptmp; //临时保存指针
ptmp1=ptmp; //保存链接表第一个节点的指针
}
else // 不是第一个节点
{
ptmp=new listrec; //申请内存空间,取得分配成功后指向该节点的指针
Pnew->next=ptmp; //Pnew中存放的是上一个节点的指针
Pnew=ptmp; //保存当前指针作为下一个节点的上级节点指针
}
}
Pnew->next=(struct listrec *)NULL; //最后一个节点的下一个初始化为指向NULL
给各节点赋值 (为明了起见赋值没有放在上面的循环中,其实是可以放在上面循环中赋值各节点)
Pnew=ptmp1; //取得指向第一个节点的指针
i=1;
CString xx;
xx="aa";
while (Pnew != (struct listrec *)NULL)
{
Pnew->value=i;
Pnew->str=xx;
Pnew=Pnew->next; //指向下一个节点
i++;
xx=xx+"aa";
}
十个节点的value分别为1,2,3….10;
十个节点的str 分别为aa,aaaa,aaaaaa,…………, aaaaaaaaaaaaaa;
为了更好第理解指针及构造的链接表,我在vc6。0环境下写了个小程序来显示节点的值及各个值的地址,看到这些值在内存中的地址,我觉得有助于对指针的理解。
还是针对上面构造的10个节点的链接表(xx为上面的Cstring定义,m_edit为添加的控件edit的变量用于显示
Pnew=ptmp1; //取的指向第一个节点的指针,构造时保存在ptmp1中
m_edit=m_edit+"p->value p->str P &P->value &P->str P->next" +"\r\n";
while (Pnew != (struct listrec *)NULL)
{
xx.Format("%X",Pnew->value);
m_edit=m_edit+"第"+xx+"节点的值为 " +Pnew->str;
xx.Format(" %xH %xH %xH %xH",Pnew,&Pnew->value,&Pnew->str,Pnew->next);
m_edit=m_edit+xx+"\r\n";
UpdateData(FALSE);
Pnew=Pnew->next;
}
Pnew ->value Pnew ->str Pnew & Pnew ->value & Pnew ->str Pnew ->next
第1节点的值为 aa 422fe0H 422fe0H 422fe4H 422f10H
第2节点的值为 aaaa 422f10H 422f10H 422f14H 422ed0H
第3节点的值为 aaaaaa 422ed0H 422ed0H 422ed4H 422e90H
第4节点的值为 aaaaaaaa 422e90H 422e90H 422e94H 422d00H
第5节点的值为 aaaaaaaaaa 422d00H 422d00H 422d04H 422cc0H
第6节点的值为 aaaaaaaaaaaa 422cc0H 422cc0H 422cc4H 422c80H
第7节点的值为 aaaaaaaaaaaaaa 422c80H 422c80H 422c84H 422c40H
第8节点的值为 aaaaaaaaaaaaaaaa 422c40H 422c40H 422c44H 422c00H
第9节点的值为 aaaaaaaaaaaaaaaaaa 422c00H 422c00H 422c04H 422bc0H
第A节点的值为 aaaaaaaaaaaaaaaaaaaa 422bc0H 422bc0H 422bc4H 0H
再看下面的用法:
Pnew=ptmp1;
m_edit=m_edit+"p->value p->str P &P->value &P->str P->next" +"\r\n";
xx.Format("%X",Pnew->value);
m_edit=m_edit+"第"+xx+"节点的值为 " +Pnew->str;
xx.Format(" %xH %xH %xH %xH",Pnew,&Pnew->value,&Pnew->str,Pnew->next);
m_edit=m_edit+xx+"\r\n\r\n";
UpdateData(FALSE);
p->value p->str P &P->value &P->str P->next
第1节点的值为 aa 422fe0H 422fe0H 422fe4H 422f10H
m_edit=m_edit+"Pnew Pnew->next (Pnew->next)->next (Pnew->next)->next)->next" +"\r\n";
xx.Format("%xH %xH %xH %xH",Pnew,Pnew->next,(Pnew->next)->next,((Pnew->next)->next)->next);
m_edit=m_edit+xx+"\r\n\r\n";
UpdateData(FALSE);
Pnew Pnew->next (Pnew->next)->next (Pnew->next)->next)->next
422fe0H 422f10H 422ed0H 422e90H
m_edit=m_edit+"Pnew (*Pnew).next (*Pnew).next->next (Pnew->next)->next)" +"\r\n";
xx.Format("%xH %xH %xH %xH",Pnew,(*Pnew).next,(*Pnew).next->next,(Pnew->next)->next);
m_edit=m_edit+xx+"\r\n\r\n";
UpdateData(FALSE);
Pnew (*Pnew).next (*Pnew).next->next (Pnew->next)->next)
422fe0H 422f10H 422ed0H 422ed0H
看到了吗
(*Pnew)<=>Pnew->next
(*Pnew).next->next <=>(Pnew->next)->next)
Pnew是指向节点的指针,而*Pnew取得了该节点的内容,可以认为是一个结构,所以可以像listrec x1;定义的x1写x1.str, x1.value, x1.next一样写成(*Pnew).next, (*Pnew).value, (*Pnew).str
而Pnew是指向结构的指针所以你不能写Pnew.next之类的语句。当然你也不能将(*Pnew).next写成*Pnew.next或(*Pnew.next)应为.的优先级高于*,所有会产生错误。