如何删除第一个结点啊??

czyf2001 2004-07-31 11:53:28
/*
* 单链表的操作
*/

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

typedef struct ys{
int data ;
struct ys *next ;
}snode ;


#define FALSE 1
#define TRUE 0
#define LEN sizeof(snode)
//#define FREE(p) {free(p) ; p=NULL;}
typedef snode* LinkList;


//删除链表
void clearList(LinkList pHead)
{
snode* pDelNode = NULL ;
while(pHead)
{
pDelNode = pHead ;
pHead = pHead->next ;
free(pDelNode) ;
}

}

// 创建单链表
snode* creatList(int k) //n表示创建结点的个数
{
int n = k-1 ;
snode* pHead = NULL ;
snode* pCurNode = NULL ;
snode* pPriNode = NULL ;
snode* pPrintNode = NULL ;
int nCount = 0 ;

if(!(pCurNode = (snode *)malloc(LEN)))
return NULL ;

pHead = pCurNode ;

pCurNode->data = rand()%100 ;
pCurNode->next = NULL ;

pPriNode = pCurNode ;

for(; nCount <n ; nCount++)
{
pCurNode = (snode*)malloc(LEN) ;
if(!pCurNode)
{
//删除已经创建的链表
clearList(pCurNode) ;
}

pCurNode->data = rand()%100 ;
pCurNode->next = NULL ;

pPriNode->next = pCurNode ;
pPriNode = pCurNode ;
}

//打印创建的链表

for(pPriNode=pHead ; pPriNode ; pPriNode=pPriNode->next)
{
printf("%4d " , pPriNode->data) ;
}
return pHead ;

}

//得到链表的长度
int getLength(LinkList pHead )
{
int length = 0 ;
while(pHead && pHead->next)
{
pHead = pHead->next ;
length ++ ;
}
return length ;
}

//得到要查找的结点k ok!
snode *GetNode(LinkList pHead , int k)
{
//在带头结点的单链表head中查找第i个结点,若找到(0≤i≤n),
//则返回该结点的存储位置,否则返回NULL。

snode* pFinNode = NULL ;
int nCount = 0 ;
if(!pHead )
return NULL ;
pFinNode = pHead ;
//假设k属于链表的范围内
while(pFinNode->next && nCount < k) // 一定要找到最后一个结点,所以用pFinNode->next !=NULL
{
pFinNode = pFinNode->next ;
++ nCount ;
}
if(nCount == k)
return pFinNode ;
else
return NULL ;

}

//在单链表中进行删除i结点
void deleteNode(LinkList pHead , int i)
{
snode* pPriNode = NULL ;
snode* pDelNode = NULL ;
snode* pPrintNode = NULL ;

//得到要删除的前一个结点 ,但是如何删除第一个结点呢????
pPriNode = GetNode(pHead , i-1) ;
pDelNode = pPriNode->next ;
pPriNode->next = pDelNode->next ;
free(pDelNode) ;

pPrintNode = pHead ;
while(pPrintNode!=NULL)
{
printf("%4d " , pPrintNode->data) ;
pPrintNode = pPrintNode->next ;
}

}

int main()
{
int count = 0 ;
int ind1 = 0 ;
int ind2 =0 ;
int listLength ;
LinkList pHead = NULL ;
snode *tmp1 , *tmp2 ;

srand((unsigned)time(NULL)) ;

pHead = creatList(6) ;
listLength = getLength(pHead) + 1 ;
printf("\n链表的长度是: %d\n" , listLength) ;
printf("输入要删除的结点号:0--%d\n" , listLength-1) ;
scanf("%d" , &ind2) ;
deleteNode(pHead , ind2) ;

printf("\n") ;
system("PAUSE") ;
return 0 ;
}

/*
请问各位大虾,是我哪里写错了 啊?为什么不可以删除第一个结点!
谢谢!
*/
...全文
272 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
newegg2002 2004-08-02
  • 打赏
  • 举报
回复
你可以在你的链表中增设一个头结点,,这样的话,你就可以用与处理其他结点一样的方法处理第一个结点了..
这是我稍微改了一下的程序,你看看:
1.创建链表的函数:
snode* creatList(int k) //n表示创建结点的个数
{
int n = k-1 ;
snode* pHead = NULL ;
snode* pCurNode = NULL ;
snode* pPriNode = NULL ;
snode* pPrintNode = NULL ;
snode* pAddHead=NULL; //在这儿增设头结点
int nCount = 0 ;


//pAddHead= pCurNode ;
// pPriNode = pCurNode ;

for(; nCount <n+1 ; nCount++)
{
pCurNode = (snode*)malloc(LEN) ;
if(!pCurNode)
{
//删除已经创建的链表
clearList(pCurNode) ;
}

pCurNode->data = rand()%100 ;
pCurNode->next = NULL ;
if (pHead==NULL) {
pHead=pPriNode=pCurNode;
}

pPriNode->next = pCurNode ;
pPriNode = pCurNode ;
}
if(!(pAddHead = (snode *)malloc(LEN))) //将头结点加入链表中
return NULL ;



pAddHead->data = rand()%100 ; //其数据域可以是任意数据
pAddHead->next = pHead ; //指针域指向第一个有数据的结点,
// pAddHead->next=pHead;

//打印创建的链表

for(pPriNode=pHead ; pPriNode ; pPriNode=pPriNode->next)
{
printf("%4d " , pPriNode->data) ;
}
return pAddHead ; //将头指针返回,,

}
2,求长度函数:
int getLength(LinkList pHead )
{
int length = 0 ;
while(pHead && pHead->next)
{
pHead = pHead->next ;
length ++ ;
}
return length-1 ; //因为多了一个头结点,所以长度应为实际的减去1
}
3,主函数:
int main()
{
int count = 0 ;
int ind1 = 0 ;
int ind2 =0 ;
int listLength ;
LinkList pHead = NULL ;
// snode *tmp1 , *tmp2 ; //没用的变量

srand((unsigned)time(NULL)) ;

pHead = creatList(6) ;
listLength = getLength(pHead) + 1 ;
printf("\n链表的长度是: %d\n" , listLength) ;
printf("输入要删除的结点号:1--%d\n" , listLength) ;
scanf("%d" , &ind2) ;
deleteNode(pHead , ind2) ;

printf("\n") ;
system("PAUSE") ;
return 0 ;
}
在这样的链表,处理所以结点可以用同样的方法,而不需要分情况,这也就是带有头结点链表的优点,,
当然你的代码也可以不作这样的修改,不过那样的话,你就要对删除第一个结点,分为另外一个情况讨论了..
czyf2001 2004-08-02
  • 打赏
  • 举报
回复
我这个里面就是有头指针的啊!
但是,我在里面增加了一些判断,感到用起来很不方便啊!
各位能给我一个更好的例子不?
谢谢1!
czyf2001 2004-08-02
  • 打赏
  • 举报
回复
//经过newegg2002(天生我菜有X用) 的提醒,这次增加了表头结点,经过验证,ok!

/*
* 单链表的操作 , 带有表头结点的单链表,有头指针
* 修改完全正确 , 2004-08-02 , zyf
*/


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

typedef struct ss{
int data ;
struct ss *next ;
}snode ;

#define FALSE 1
#define TRUE 0
#define LEN sizeof(snode)
#define FREE(p) {free(p) ; p=NULL;}

typedef snode* LinkList;


//删除链表 ok!
void clearList(LinkList pHead)
{
snode* pDelNode = NULL ;
while(pHead)
{
pDelNode = pHead ;
pHead = pHead->next ;
free(pDelNode) ;
}

}

// 创建单链表 ok !
snode* creatList(int n) //n表示创建结点的个数
{
LinkList pHead = NULL ; //头指针
LinkList pAddHead = NULL ; //增加一个表头结点
snode* pCurNode = NULL ;
snode* pPriNode = NULL ;
snode* pPrintNode = NULL ;
int nCount = 0 ;

if(!(pCurNode = (snode *)malloc(LEN)))
return NULL ;

pHead = pCurNode ;

pCurNode->data = rand()%100 ;
pCurNode->next = NULL ;

pPriNode = pCurNode ;

for(; nCount <n ; nCount++)
{
pCurNode = (snode*)malloc(LEN) ;
if(!pCurNode)
{
//删除已经创建的链表
clearList(pCurNode) ;
}

pCurNode->data = rand()%100 ;
pCurNode->next = NULL ;

if (pHead==NULL)
{
pHead=pPriNode=pCurNode;
}

pPriNode->next = pCurNode ;
pPriNode = pCurNode ;
}

//将表头结点加进去
if(!(pAddHead=(snode *)malloc(LEN)))
exit(0) ;

pAddHead->data =0 ;
pAddHead->next = pHead ;
//打印创建的链表

for(pPriNode=pHead ; pPriNode ; pPriNode=pPriNode->next)
{
printf("%4d " , pPriNode->data) ;
}
return pAddHead ;

}

//在单链表中查找数据元素key, ok !
snode* findKey(LinkList pHead , int key)
{
snode* pFindNode = NULL ;
if(!pHead)
return NULL ;
pFindNode = pHead ;

while(pFindNode->next && pFindNode->data!=key) //必须要找到pFindNode->next,表示到最后一个结点 ,ok !
{
pFindNode = pFindNode->next ;
}
if(pFindNode->data==key && pFindNode)
return (pFindNode) ;
else
return NULL ;
}


//得到要查找的结点k ok!
snode *getNode(LinkList pHead , int k)
{
snode* pFinNode = NULL ;
int nCount = 0 ;
if(!pHead )
return NULL ;
pFinNode = pHead ;
//假设k属于链表的范围内

while (pFinNode->next && nCount < k) // 一定要找到最后一个结点,所以用pFinNode->next !=NULL
{
pFinNode = pFinNode->next ;
++ nCount ;
}
if(nCount == k)
return pFinNode ;
else
return NULL ;

}


//在单链表中进行删除i结点 , ok !
void deleteNode(LinkList pHead , int i)
{
snode* pPriNode = NULL ;
snode* pDelNode = NULL ;
snode* pPrintNode = NULL ;
/*
if(i==0)
{
printf("heh\n") ;
pDelNode = pHead;
pHead = pHead->next ;
FREE(pDelNode) ;
}

//得到要删除结点的前一个点
else
*/
{

pPriNode = getNode(pHead , i-1) ;
pDelNode = pPriNode->next ;
pPriNode->next = pDelNode->next ;
free(pDelNode) ;
}
pPrintNode = pHead->next ; // 由pPrintNode = pHead 改成这样: pPrintNode = pHead->next ;
while(pPrintNode!=NULL)
{
printf("%4d " , pPrintNode->data) ;
pPrintNode = pPrintNode->next ;
}

}

//在 x 结点处插入元素 key , ok !
void insertKey(LinkList pHead , int x , int key)
{
snode* pPriNode = NULL ;
snode* pInserNode = NULL ;
snode* pPrintNode = NULL ;
/*
if(x==0)
{
printf("\n在表头处插入元素: %d\n" , key) ;
pInserNode = (snode*)malloc(LEN) ;
if(!pInserNode)
{//分配空间错误处理
fprintf(stderr , "分配空间出错\n") ;
exit(1) ;
}
pInserNode->data = key ;
pInserNode->next = pHead ;
pHead = pInserNode ;

}

else
*/
{

pPriNode = getNode(pHead , x-1) ;
pInserNode = (snode*)malloc(LEN) ;
if(!pInserNode)
{/*分配空间错误处理*/
fprintf(stderr , "分配空间出错\n") ;
exit(1) ;
}

pInserNode->data = key ;
pInserNode->next = pPriNode->next ;
pPriNode->next = pInserNode ;

}

printf("插入key之后的新链表是: \n") ;
pPrintNode = pHead->next; // 由于增加了表头结点将:pPrintNode = pHead 改成: pPrintNode = pHead->next;
while(pPrintNode!=NULL)
{
printf("%4d " , pPrintNode->data) ;
pPrintNode = pPrintNode->next ;
}


}

//得到链表的长度 , ok !
int getLength(LinkList pHead )
{
int length = 0 ;
while(pHead && pHead->next)
{
pHead = pHead->next ;
length ++ ;
}
return length ; //由于增加了表头结点,故长度应该减1
}





int main()
{
int count = 0 ;
int ind1 = 0 ;
int ind2 =0 ;
int ind3 = 0 ;
int listLength ;
LinkList pHead = NULL ;
snode *tmp1 , *tmp2 ;

srand((unsigned)time(NULL)) ;

pHead = creatList(6) ;
listLength = getLength(pHead) ;
printf("长度是: %d\n" , listLength) ;

printf("输入元素进行查找:\n") ;
scanf("%d" , &count) ;
tmp1 = findKey(pHead , count) ;
if(tmp1)
printf("find yes\n") ;
else
printf("not find \n") ;

//查找结点号

printf("开始查找结点号,请输入结点号 :\n") ;
scanf("%d" , &ind1 ) ;
if(ind1 > listLength)
{
printf("error !!") ;
exit(0) ;
}
tmp2 = getNode(pHead , ind1) ;
printf("查找的结点号是: %d 该结点号对应的元素是: %d\n" , ind1 , tmp2->data ) ;

printf("插入一个元素后\n") ;
insertKey(pHead , 1 , 400) ;

printf("输入要删除的结点号:1--%d\n",listLength) ;
scanf("%d" , &ind2) ;
if(ind2 > listLength)
{
printf("error !!") ;
exit(0) ;
}

deleteNode(pHead , ind2) ;

/*
//插入一个元素
printf("请输入将插入一个元素的位置:\n") ;
scanf("%d" , &ind3) ;
insertKey(pHead , ind3 , 100) ;
*/
printf("\n") ;
system("pause") ;
return 0 ;
}


//结贴
ber 2004-07-31
  • 打赏
  • 举报
回复
if(!pHead)
return NULL;
看错了,直接return;行了

这个函数不好,没法从返回值确定删除操作是否成功
ber 2004-07-31
  • 打赏
  • 举报
回复
//在单链表中进行删除i结点
void deleteNode(LinkList pHead , int i)
{
snode* pPriNode = NULL ;
snode* pDelNode = NULL ;
snode* pPrintNode = NULL ;

//得到要删除的前一个结点 ,但是如何删除第一个结点呢????
//这样试试

if(!pHead)
return NULL;
pPriNode = i ? GetNode(pHead , i-1) : pHead ;
pDelNode = i ? pPriNode->next : pHead ;
pPriNode->next = pDelNode->next ;
free(pDelNode) ;

pPrintNode = pHead ;
while(pPrintNode!=NULL)
{
printf("%4d " , pPrintNode->data) ;
pPrintNode = pPrintNode->next ;
}

czyf2001 2004-07-31
  • 打赏
  • 举报
回复
我这个里面就是有头指针的啊!
但是,我在里面增加了一些判断,感到用起来很不方便啊!
各位能给我一个更好的例子不?
谢谢1!
KingI 2004-07-31
  • 打赏
  • 举报
回复
设p1为第一结点
head->next=p1->next
zchuer 2004-07-31
  • 打赏
  • 举报
回复
放个头指针吧
czyf2001 2004-07-31
  • 打赏
  • 举报
回复
//上面的贴错了!
/*
* 单链表的操作
*/


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

typedef struct ys{
int data ;
struct ys *next ;
}snode ;


#define FALSE 1
#define TRUE 0
#define LEN sizeof(snode)
//#define FREE(p) {free(p) ; p=NULL;}
typedef snode* LinkList;





//删除链表
void clearList(LinkList pHead)
{
snode* pDelNode = NULL ;
while(pHead)
{
pDelNode = pHead ;
pHead = pHead->next ;
free(pDelNode) ;
}

}

// 创建单链表
snode* creatList(int k) //n表示创建结点的个数
{
int n = k-1 ;
snode* pHead = NULL ;
snode* pCurNode = NULL ;
snode* pPriNode = NULL ;
snode* pPrintNode = NULL ;
int nCount = 0 ;

if(!(pCurNode = (snode *)malloc(LEN)))
return NULL ;

pHead = pCurNode ;

pCurNode->data = rand()%100 ;
pCurNode->next = NULL ;

pPriNode = pCurNode ;

for(; nCount <n ; nCount++)
{
pCurNode = (snode*)malloc(LEN) ;
if(!pCurNode)
{
//删除已经创建的链表
clearList(pCurNode) ;
}

pCurNode->data = rand()%100 ;
pCurNode->next = NULL ;

pPriNode->next = pCurNode ;
pPriNode = pCurNode ;
}

//打印创建的链表

for(pPriNode=pHead ; pPriNode ; pPriNode=pPriNode->next)
{
printf("%4d " , pPriNode->data) ;
}
return pHead ;

}

//在单链表中查找数据元素key
snode* findKey(LinkList pHead , int key)
{
snode* pFindNode = NULL ;
if(!pHead)
return NULL ;
pFindNode = pHead ;

while(pFindNode->next && pFindNode->data!=key) //必须要找到pFindNode->next,表示到最后一个结点 ,ok !
{
pFindNode = pFindNode->next ;
}
if(pFindNode->data==key && pFindNode)
return (pFindNode) ;
else
return NULL ;
}


//得到要查找的结点k ok!
snode *getNode(LinkList pHead , int k)
{
snode* pFinNode = NULL ;
int nCount = 0 ;
if(!pHead )
return NULL ;
pFinNode = pHead ;
//假设k属于链表的范围内

while (pFinNode->next && nCount < k) // 一定要找到最后一个结点,所以用pFinNode->next !=NULL
{
pFinNode = pFinNode->next ;
++ nCount ;
}
if(nCount == k)
return pFinNode ;
else
return NULL ;

}


//在单链表中进行删除i结点
void deleteNode(LinkList pHead , int i)
{
snode* pPriNode = NULL ;
snode* pDelNode = NULL ;
snode* pPrintNode = NULL ;

//增加判断如下:
if(i==0)
{
printf("heh\n") ;
pDelNode = pHead;
pHead = pHead->next ;
free(pDelNode) ;
}

//得到要删除结点的前一个点
else
{

pPriNode = getNode(pHead , i-1) ;
pDelNode = pPriNode->next ;
pPriNode->next = pDelNode->next ; //上面的那个写错了, pPriNode->next = pDelNode ;
free(pDelNode) ;
}
pPrintNode = pHead ;
while(pPrintNode!=NULL)
{
printf("%4d " , pPrintNode->data) ;
pPrintNode = pPrintNode->next ;
}

}

//在 x 结点处插入元素 key
void insertKey(LinkList pHead , int x , int key)
{
snode* pPriNode = NULL ;
snode* pInserNode = NULL ;
snode* pPrintNode = NULL ;

pPriNode = getNode(pHead , x-1) ;
pInserNode = (snode*)malloc(LEN) ;
if(!pInserNode)
{/*分配空间错误处理*/
fprintf(stderr , "分配空间出错\n") ;
exit(1) ;
}

pInserNode->data = key ;
pInserNode->next = pPriNode->next ;
pPriNode->next = pInserNode ;

printf("插入key之后的新链表是: \n") ;
pPrintNode = pHead ;
while(pPrintNode!=NULL)
{
printf("%4d " , pPrintNode->data) ;
pPrintNode = pPrintNode->next ;
}


}

//得到链表的长度
int getLength(LinkList pHead )
{
int length = 0 ;
while(pHead && pHead->next)
{
pHead = pHead->next ;
length ++ ;
}
return length ;
}





int main()
{
int count = 0 ;
int ind1 = 0 ;
int ind2 =0 ;
int listLength ;
LinkList pHead = NULL ;
snode *tmp1 , *tmp2 ;

srand((unsigned)time(NULL)) ;

pHead = creatList(6) ;
listLength = getLength(pHead) + 1;
printf("长度是: %d\n" , listLength) ;
/*
printf("输入元素进行查找:\n") ;
scanf("%d" , &count) ;
tmp1 = findKey(pHead , count) ;
if(tmp1)
printf("find yes\n") ;
else
printf("not find \n") ;

//查找结点号

printf("开始查找结点号,请输入结点号 :\n") ;
scanf("%d" , &ind1 ) ;
if(ind1 > listLength)
{
printf("error !!") ;
exit(0) ;
}
tmp2 = GetNode(pHead , ind1) ;
printf("查找的结点号是: %d 该结点号对应的元素是: %d\n" , ind1 , tmp2->data ) ;

printf("插入一个元素后\n") ;
insertKey(pHead , 5 , 400) ;
*/
printf("输入要删除的结点号:1--%d\n",listLength) ;
scanf("%d" , &ind2) ;
if(ind2 > listLength)
{
printf("error !!") ;
exit(0) ;
}

deleteNode(pHead , ind2) ;
/*
//插入一个元素
printf("插入一个元素后\n") ;
insertKey(pHead , 3 , 100) ;
*/
printf("\n") ;
return 0 ;
}

//有没有更好的办法啊?






















czyf2001 2004-07-31
  • 打赏
  • 举报
回复
在deleteNode增加一个判断,则可以了!
//在单链表中进行删除i结点
void deleteNode(LinkList pHead , int i)
{
snode* pPriNode = NULL ;
snode* pDelNode = NULL ;
snode* pPrintNode = NULL ;




if(i==0)
{
printf("heh\n") ;
pDelNode = pHead;
pHead = pHead->next ;
free(pDelNode) ;
}

//得到要删除结点的前一个点
else
{
pPriNode = getNode(pHead , i-1) ;
pDelNode = pPriNode->next ;
pPriNode->next = pDelNode ;
free(pDelNode) ;
}
pPrintNode = pHead ;
while(pPrintNode!=NULL)
{
printf("%4d " , pPrintNode->data) ;
pPrintNode = pPrintNode->next ;
}

}

//但是我认为这样总不是最好的办法,谁能告诉我一个更好的办法不?
谢谢!
czyf2001 2004-07-31
  • 打赏
  • 举报
回复
还是不行啊!
当我输入要删除的结点号为0时,或者为1时,都是删除了下标为1的结点啊!

why?

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧