单链表部分

// *******************************单链表部分


// 程序员面试宝典 单链表 168  面试题目1 编程实现单链表的建立,测长,和打印。  (参考代码写的很差劲呢,建议参考一下数据结构书籍)
/*
#include "CodeTest.h"
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <conio.h>
using namespace std;


  typedef int ElemType ;
  typedef struct student
  {
  ElemType data;
  struct student * next;
  }node;
  //***********************
  // 测试主函数
  int main()
  {
  Status status;
  node * create();
  int length(node*);
  void print(node*); 
  Status del(node * ,int, ElemType*);
  Status insert(node * ,int, ElemType*);
  Status reverse(node *head);// 函数声明
  
node *p;
ElemType x=0;
p=create();// 创建链表
if(p)
{
printf("\nThe length of list is:%d",length(p));// 链表长度
print(p); // 打印链表
}

 status=del(p,2,&x);// 删除第二个节点
 if(status)
 {
 printf("\nThe delete data  is:%d",x);// 打印删除的数据x
 printf("\nThe length of list is:%d",length(p));// 链表长度
 print(p);// 打印链表
 }
 
status=insert(p,2,&x);// 插入第二个节点
if(status)
{
printf("\nThe insert data  is:%d",x);// 打印插入的数据x
printf("\nThe length of list is:%d",length(p));// 链表长度
print(p);// 打印链表
}

 status=reverse(p);
 if(status)
 {
 printf("\nThe length of list is:%d",length(p));// 链表长度
 print(p);// 打印链表
 }
 

 printf("\n main END\n");
 return 0;
 }
 
//***********************
// 根据输入数据创建单链表 有头结点
node * create()
{
node *head,*p,*s; // p,s 均是游标
int x,cycle=1;
head =(node *)malloc(sizeof(node)); // 生成头结点
p=head;// 尾节点=头结点
printf("\nplease input one int datas,(must end with 0):");// 一次性输入所有数据。
while(cycle)
{
//printf("\nplease input one int data :");// 提示一次,输入一个整型数据.
scanf("%d",&x);//ElemType==int;
if(x!=0) // 如果输入为0 则节点创建结束,否则继续。
{
s=(node *) malloc(sizeof (node)); // 创建新节点
s->data=x; 
// printf("\nData:%d",s->data);
p->next=s;// 尾节点链接新节点
p=s;//更新尾节点位置
}
else cycle=0;
}
//head=head->next; // 更新头结点为下一个有用节点。如果头结点不存储数据,则注释此语句。
p->next=NULL;
//printf("\n data %d", head->data);
return (head);// 返回头指针。
}
//***********************
// 求单链表长度 (有头结点)
int length(node *head)
{
int n =0;
node *p ;
if(head!=NULL)// 头结点非空
{
p=head->next;
}
while(p!=NULL)
{
p=p->next;
n++;
}
return(n);
}
//***********************
// 单链表打印 (有头结点)
void print(node *head)
{
node *p; 
int n;
n=length(head);
printf("\nNow These %d records are :\n",n);

 if(head!=NULL)
 {
 p=head->next;// 假设头结点不存储有效数据。
 while(p!=NULL)
 {
 printf("%4d",p->data);
 p=p->next;
 }
 }
 printf("\nPrint End!\n");
 }
 
//***********************
// 单链表的数据节点删除
// 《程序员面试宝典》 168 面试题2 单链表删除节点
// 《数据结构》严蔚敏,算法2.10
// 函数功能:在带头结点的单链线性表L中,删除第i个节点,并由e返回其数值。
// 函数思路:先找到删除节点的前一个节点(第(i-1)个节点),让其指向第(i+1)个节点。释放第i个节点空间,指针赋值空。(只能用于至少有2个节点的情况)
// 函数边界:要删除的节点是头结点;尾节点;中间节点。输入参数合法性检查。
Status del(node *L ,int i, ElemType *e )

node *p,*q;
int j=0;
p=L;
while(p->next && j<i-1) // 搜索到第i-1个节点, 如果是头结点i=1,则跳过
{
p=p->next; 
++j;
}    

 // 参数i 合法性检查:  0<i<length(L)
 // 如果删除位置i>表长 则会导致p->next==NUll; // 如果删除位置小于等于0,则导致j>i-1;
 if(!(p->next )||j>i-1) return ERROR;//删除位置不合理。
 q=p->next;// q指向第i个节点
 p->next=q->next;// 让第i-1个节点指向第i+1个节点;
 *e=q->data;
 free(q);// 释放掉第i个节点内存。
 q=NULL;
 return OK;
 }
 
//***********************
// 单链表数据节点的插入
//  《程序员面试宝典》 168 面试题3 单链表插入节点
// 《数据结构》严蔚敏,算法2.9
// 函数功能:在带头结点的单链线性表L中,第i个节点之前,插入一个新节点。                                          
// 函数思路:先让插入的节点s指向后一个节点(i),(该地址要由第i-1个节点p获取)。然后,让i-1节点指向s节点。最后形成: i-1-> s ->i
// 函数边界:要插入的节点是头结点;尾节点;中间节点。输入参数合法性检查。

 Status insert(node *L ,int i, ElemType *e )
 { 
 node *p,*s;
 int j=0;
 p=L; // 有头结点
 while(p && j<i-1) // 搜索到第i-1个节点
 {
 p=p->next; 
 ++j;
 }
 
// 参数i 合法性检查:  0<i<length(L)+1
// 如果插入位置i>表长+1 则会导致p==NUll; // 如果删除位置小于1,则导致j>i-1;
if(!p||j>i-1) return ERROR;//插入位置不合理。i<1或者大于表长+1;
s=(node*) malloc(sizeof(node));
s->data=*e;
s->next=p->next; //让插入的节点s指向后一个节点(i)
p->next=s;//让i-1节点指向s节点。
return OK;
}

 //***********************
 // 单链表的逆序
 // 程序员面试宝典p170  编程实现单链表的逆序。
 // 思路:  p1 p2 p3 p1 p2 p3  p1 p2 p3             p1 p2 (收尾处理)
 //      h->A->B->C->D->NULL   第一步 A<-B->C->D->NULL   A<-B<-C->D->NULL, A<-B<-C<-D,(NULL)(由上一次循环获得)      NULL<-A<-B<-C<-D<-h   利用p1,p2,p3指针不断的重复操作即可。
 // 特例: 空节点和单节点。
 // 测试用例: 1 2 3 4 5 ---》 5 4 3 2 1 
 
Status  reverse(node *head)
{
node *p1,*p2,*p3 ;// 游标
if(head==NULL || head->next==NULL || head->next->next==NULL) //只有头节点或只有一个数据节点
return OK;
// 有头节点,头结点不存储数据,所以p1要越过头结点
p1=head->next;// 第一个数据节点
p2=p1->next;// 第二个数据节点

 while(p2) // p1不是最后一个节点,p2非空。
 {
 p3=p2->next;
 p2->next=p1;// 指向倒转
 p1=p2; // 游标滑动
 p2=p3;
 }
 // 收尾处理
 head->next->next = NULL; // 原来的首节点现在变成了尾节点, A->next= NULL;
 head->next=p1; //头结点指向现在的首节点
 printf("\n Reverse the List!\n");
 return OK;
 
}

 // 面试题4 编程实现单链表排序
 

*/






//***********************
//题目: 找到单向链表中间的那个元素,如果有两个则取前面一个。
//思路: 设定两个指针p,q,跳动步伐为1,2,p跳动到尾部的时候,q正好在中间。(有个细节:p不敢直接两步跳,有缺陷,而是先跳一步,检查是否是NULL,然后再跳一步)
//        p跳两步后,q跳一步。 所以不敢(p=p->next->next ; q=q->next)。
//答案:
/*
#include <iostream>
using namespace std;


  typedef struct node 
  {
  int value;
  node* next;
  }Lnode,*Pnode;
  

 int find_mid(Lnode* head)
 {
 Lnode* pre,*curr;
 curr = head; // 两步跳
 pre = head;  // 单步跳
 

 for (int i = 1; curr != NULL; curr = curr->next, i ++)
 {
 if (i%2 == 0)
 {
 pre = pre->next;
 }
 
}
return pre->value;

 }
 //有头结点
 int main()
 {
 Lnode* head = new Lnode;
 head->next = NULL;
 
Lnode* nod = head;
int val;

 cout << "输入数据(int类型,以0结束): ";
 cin >> val;
 
while (val != 0) // 输入数据以0结束
{
Lnode* curr = new node;

 curr->value = val;// 新节点
 curr->next = NULL;
 
nod->next = curr; //前一节点
nod = nod->next;// 更新前一节点游标,当前节点成为下一个节点的前一节点

 cin >> val;
 }
 
cout << "链表数据为:";
for (Lnode* pre = head->next;pre!=NULL;pre=pre->next)
{
cout << pre->value  <<" ";
}
cout << endl;

 cout << "中间的数是:" << find_mid(head) << endl;
 
return 0;
}
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值