一个节点由一个数据域data和一个指针域next构成。因线性表中第一个节点无前驱,所以设立一个头指针来指向第一个节点,因最后一个节点无后继所以最后一个节点的指针域为NULL。
为了操作方便一般先设立一个头结点,所以此时头指针指向的节点为头结点。而不再指向表中的第一个节点。
指针与指针变量区别:
指针变量,顾名思义,就是一个变量,其值是可变的,与整形变量、浮点变量等等的命名规则完全相同。
例如:int *p;
指针存放的是地址,指针变量存放的是数据。
题1:完成List CreateList();函数,该函数创建一个带头节点的单链表。
List CreateList()
{
List L=(Node*)malloc(sizeof(Node));//申请头结点空间
L->next=NULL;//空的头结点
return L;
}
题2:完成Position Locate(List L,ElemType X)函数,该函数在链表L中查找是否结点的数据等于X,如果存在,返回该结点的指针,否则返回NULL。(没有说明该链表是否带头节点)
Position Locate(List L,ElemType X)
{
Node *p;
p=L->next;//从第一个节点开始查找
while(p!=NULL)
{
if(p->data!=X)
{
p=p->next;//若没有找到指针不断下移。
}
else
break;
}
return p;
}
题3:完成Position Get(List L,int k)函数,该函数在链表L中查找第k个结点,如果存在则返回该结点的指针,否则返回NULL,其中L是带头节点的链表,k从1开始计数。
Position Get(List L,int k)
{
Node *p;
int i;
p=L,i=0;//先为头指针
if(k<=0)
return NULL;
while(p->next!=NULL&&(i<k))
{
p=p->next;
i++;
}
if(i==k)return p;
else
return NULL;
}
题4:完成int ListLength(List L)函数,该函数在链表L中数据结点的数目,即链表长度。
疑问(头结点算不算数据节点)头结点是指向第一个元素的节点,此节点中没有数据,即是不携带信息;
int ListLength(List L)
{
Node *p;
int i=0;
p=L->next;
while(p!=NULL)
{
p=p->next;
i++;
}
return i;
}
题5:完成bool ListDelNode(List L,int k,ElemType *e)函数,该函数在链表L中删除第k个结点,如果删除成功返回true,并在指针e中保存删除结点的数据,否则返回false。
bool ListDelNode(List L,int k,ElemType *e)
{
Node *p,*r;
int i=0;
p=L;
while(p->next!=NULL&&i<k-1)
{
p=p->next;
i++;
}
if(p->next==NULL)
{return false;}
r=p->next;
p->next=r->next;//即p->next=p->next->next;
*e=r->data;
free(r);
return true;
}
题6:完成void InsertAtHead(List L,ElemType X)函数,该函数在链表L中用头插法的插入数据X,其中L是带头节点的链表。void InsertAtHead(List L,ElemType X) (头插法:在头结点L之后插入数据)
{
Node *p;
p=(Node *)malloc(sizeof(Node));//申请一块新的节点
p->data=X;
p->next=L->next;
L->next=p;
}
题7:完成void InsertAtTail(List L,ElemType X)函数,该函数在链表L中用尾插法的插入数据X,其中L是带头节点的链表。
void InsertAtTail(List L,ElemType X) 尾插法关键在于先定义一个指针寻找到尾巴,然后再执行插入。
{
Node *p,*q;
q=L;
while(q->next!=NULL)
{
q=q->next;
}
p=(Node*)malloc(sizeof(Node));
p->data=X;
q->next=p;
q=p;
}