链表1

一、线性链表的概念

先让我们看下面的说明部分

type

    point=^node;

    node=record

           data:integer;

           next:point;

         end;

var p,q:point;

细心的同学可以发现:指针变量有pq两个,其基类型为nodenode是一个自定义记录类型,有两个域:一个域名为data,类型为整型,另一个域名为next,类型为point型,意思是可以存放另一个node类型存储单元的地址。这里对类型的说明使用了递归的方法。

假设在程序段中出现(如图 10-7所示):

new(p);new(q);    {申请两个存储单元}

p^.data:=120;p^.next:=q;{确定指针变量p所指的存储单元的data域的值为120,将变量q所指的存储单元地址赋给pnext域中}

 

通过上述方法我们就可以将表面上独立的两个存储单元通过指针域连接在一起。依此类推,如果有多个存储单元通过类似的方法进行连接的话,就形成了一个“链”,链中的每一个单元称为“链”中的一个“结点”。一般的,把若干个结点按某一规定的顺序,通过指针域接在一起形成的链,我们称为线性链表。其结构图如下图 10-8所示:

 

需要说明的是上图中每一个结点顶端的数字表示的是该存储单元的地址值,链表中的第一个结点称为表头,最后一个元素称为表尾。指向链表头的指针称为头指针(head),表尾结点的指针域值为空(NIL)。从上图中我们可以看出,链表的特点是除第一个结点和最后一个结点外,每一个结点中都有一个直接的前趋结点和一个直接的后继结点。相邻结点的地址是互不连续的,它们靠指针域将相互间的关系连接起来。

链表的基本操作主要有链表的建立、链表的遍历、链表中结点数据的访问、向链表中插入一个结点、从链表中删除一个结点等,这些操作无一不是从指针域入手加以考虑的。

可见,链表是动态数据结构的最基本形式。它是一个结点的序列,其中的每一个结点被链接到它前面的结点上。在链表中每个结点有两个部分:一个是数据部分(可以是一个或多个),另一个是指向下一个结点的指针域,有一个头指针指向链表的表头结点,表尾结点的指针域应为NIL1表示表的结束。

二、线性链表的建立

一个线性链表的建立过程简单地说分三步:

申请新结点;

在结点的数据域填相应数据,在指针域填NIL;

将结点链接到表中某一位置。

如果组成链表的各结点只有一个用来指向下一结点的域,则我们称这样的链表为单向链表(即只能从前一结点边接到后一结点,而后一结点不能边接到前一结点)。单向链表的结构示意图,如图10-8所示。

现在我们通过前面定义这样的这个指针结构来看看单向链表的一些相关操作:

    type

    point=^node;

    node=record

           data:integer;

           next:point;

         end;

var head,last,next:point;

    x:integer;

begin

  readln(x);

  new(head);

  head^.data:=x;

  last:=head;

  read(x);

  while x>=0 do

    begin

      new(next);

      next^.data:=x;

      last^.next:=next;

      last:=next;

      read(x)

    end;

    last^.next:=nil

end.

输入一个正整数序列,遇负数时停止,以此建立一个按输入顺序排列的线性链表。

所需的数据类型说明:

type

point=^node;

node=record

       data:integer;

       next:point;

    end;

变量说明为:

var

  p,q,head:point;{p用于存放新申请的结点的地址,q用于存放目前已建立链表的尾结点的地址}

  x:integer;

算法如下:

从空表开始,头指针置NIL;

读入一个数;

while读入的数为正整数do

begin

if 要填数据的结点为头结点

   then  begin

          申请新结点;

          填新结点数据域,指针域置NIl;

          设置头、尾指针都指向新结点;

        end;

   else begin

         申请新结点;

         将读入的数送入新结点的数据域,指针域置NIL

         将新结点链接到已有的表的表尾;

尾指针后移一个结点,调整尾指针指向新的表尾(为连接下一个新结点作准备);

       end;

读下一个数;

       end;

参考程序:

head:=NIL;

read(x);

while x>=0 do begin

  if head=NIL

then  begin new(p);p^.data:=x;p^.next:=NIL;q:=p;head:=p end

else begin

     new(p);

    p^.data:=x;p^.next:=NIL;q^.next:=p;q:=p;

   end;

read(x)

end;{while}

三、线性链表的遍历与输出

一个链表的遍历输出过程就是从表头结点开始按链接的顺序依次访问至表尾的过程。解决方法如下:

设临时工作变量p指针指向链表的头结点(头结点的地址不能丢失和改变,否则会丢失整个链表);

p:=head;

 

while p<>nil do

begin

            输出p所指结点(当前结点)的数据值;

            p移向后一个结点;

           end;

          while p<>nil do

beign

        write(p^.data:8);p:=p^.next

end;

2.将两个有序单链表AB中数据域值相同的结点组成一个新链表。

问题分析:该问题实际上就是如何建立新链表,只不过链表中结点的数据域是通过两个有序链表的数据域进行比较得到的。

参考程序:

program aa;

type

  point=^node;

  node=record

   data:integer;

   next:point;

  end;

var

  head1,head2,head3:point;

procedure creat(var head:point);

  var

    p,q:point;

    x:integer;

  begin

    head:=nil;read(x);

    while x>=0 do

      begin

        if head=nil then

          begin

            new(p);head:=p;p^.data:=x;p^.next:=nil;q:=p

          end

        else begin

              new(p);q^.next:=p;p^.data:=x;q:=p

            end;

          read(x)

         end;

       q^.next:=nil

     end;

procedure same(head1,head2:point;var head3:point);

  var

    p1,p2,p,q:point;

  begin

    p1:=head1;p2:=head2;head3:=nil;q:=head3;

    while p1<>nil do

     begin

       while p2<>nil do

         begin

           if p1^.data=p2^.data then

             if head3=nil then begin

                              new(p);head3:=p;

                              p^.data:=p1^.data;

                              q:=p

                            end

                        else begin

                             new(p);q^.next:=p;

                             p^.data:=p1^.data;

                             q:=p

                            end;

           p2:=p2^.next

        end;

      p2:=head2;p1:=p1^.next

    end;

    q^.next:=nil

  end;

procedure print(head:point);

  var

    p:point;

  begin

    p:=head;

    while p<>nil do begin

                    write(p^.data:6);

                    p:=p^.next

                   end;

     writeln

   end;

begin

  write(‘input the first link:’);

  creat(head1);   print(head1);

  write(‘input the second link:’);

  creat(head2);   print(head2);

  same(head1,head2,head3);

  if head3=nil then writeln(‘no solution!’)  else print(head3)

end.

测试运行结果如下:

输入:input the first link:2 3 6 8 9 7 -1

      input the second link:3 5 9 -1

输出:3 9

输入:input the first link:2 3 5 7 -1

      input the second link:4 6 8 -1

输出:no solution!

四、线性链表的查找

对于链表的查找是指在链表中找出符合条件的结点。查找的过程如下:

设临时工作变量p指针指向链表的头结点;

while (未找到) and (未到表尾) do

if 找到 then 退出循环

else p 移向下一个结点;

if 到了表尾 then 输出“未找到” else (找到)对p所指结点进行相应的处理。

为了能够表示出是否找到结点,在程序段中用到了一个布尔型的变量found,若找到,found的值为true,若找不到found的值为false

参考程序段:

write(‘input a data for look for:’);

      readln(x);

      p:=head;

      found:=false;

      while (p<>nil) and not (found) do

begin

      if x=p^.data then found:=true

                else p:=p^.next;

      end;

if found then writeln(p^.data)

           else writeln(‘no found’);

 

习题

1.完善程序

设有一非空链表,表头结点指针为head,下面的程序是找出链表中所有结点数据域的最大值。

program aa;

type point=^node;

    node=record

         data:integer;

         link:point

        end;

var temp:integer;

     p,head:point;

begin

  ……             {建立一非空链表}

  temp:=0;p:=head;

  while  (p<>nil              )  do

     begin

       if (p^.data>temp                      )  then temp:=p^.data;

       (p:=p^.next                      )                       

     end;

  writeln(‘the max number is: ’,temp)

end.

2. 编一过程打印链表head中的所有整数,5个一行

分析:设置一个工作指针P,从头结点顺次移到尾结点,每移一次打印一个数据。 

  过程如下:

  procedure print(head:pointer);

  var p:pointer; n:integer;

  begin

   n:=0;p:=head;

   while p<>nil do

    begin

     write(p^.data:8);n:=n+1;

     if n mod 5=0 then writeln;

     p:=p^.next;

    end;

   writeln;

  end;

 

完整程序参考:

program aa;

 type point=^node;

      node=record

       data:real;

       next:point;

 end;

 var

  p,q,head:point;

  x:real; i:integer;

 begin

  read(x);

  head:=nil;

  while x>=0 do

   begin

    if head=nil then

     begin

      new(p);

      p^.data:=x;

      p^.next:=nil;

      q:=p;

      head:=p;

     end else

      begin

       new(p);

       p^.data:=x;

       p^.next:=nil;

       q^.next:=p;

       q:=p;

      end;

    read(x);

   end;

  p:=head;

  while p<>nil do

   begin

    write(p^.data,' ');

    p:=p^.next;

   end;

 

  p:=head;

  while p<>nil do

   begin

    if p^.data=(p^.data div 1)  then

     begin

      write(p^.data:0:0,' ');

      i:=i+1;

      if i mod 5=0 then writeln;

     end;

    p:=p^.next;

   end;

 end.

 

3. 编写一个过程,将读入的一串整数存入链表, 并统计整数的个数

分析:过程的输入为一串整数,这在执行部分用读语句完成。过程的输出有两个:一是链表的头指针,一是整数的个数,这两个输出可以用变量形参来实现。 

  由于不知道整数的个数,我们用一个特殊的9999作为结束标记。

 

  过程如下:

  procedure creat(var h:pointer;var n:integer);

  var p,q:pointer;x:integer;

  begin

    n:=0;h:=nil; read(x);

    while x<>9999 do

    begin

     New(p);

     n:=n+1;p^.data:=x;

     if n=1 then h:=p

     else q^.next:=p;

     q:=p;

read(x)

    end;

    if h<>nil then q^.next:=nil;

    Dispose(p);

  end;

完整程序参考:

program aa;{Input a data to delete.}

 type point=^node;

      node=record

       data:integer;

       next:point;

 end;

 var

  p,q,head:point;

  a,x,i:integer;

 f:boolean;

 procedure creat;

 var p,q,head:point;

     i:integer;

 begin

  read(x);

  head:=nil;

  i:=0;

  while x>=0 do

   begin

    if head=nil then

     begin

      new(p);

      p^.data:=x;

      p^.next:=nil;

      q:=p;

      head:=p;

      i:=i+1;

     end else

      begin

       new(p);

       p^.data:=x;

       p^.next:=nil;

       q^.next:=p;

       q:=p;

       i:=i+1;

      end;

    read(x);

   end;

  p:=head;

  while p<>nil do

   begin

    write(p^.data,' ');

    p:=p^.next;

五、线性链表结点的插入

由于线性链表结点物理地址的非连续性,对于结点的插入事实上就是改变线性链表中某结点的后继指针的值。根据插入位置的不同,我们分三种不同的情况进行分析:表头插入,表中插入和表尾插入。

 

表头插入

 

 

 

 

 

算法描述

申请一新结点newpoint

输入的数赋给newpoint的数据域;

head的值赋给newpoint的指针域;

newpoint结点的地址赋给head

参考程序段:

new(newpoint);readln(x);newpoint^.data:=x;

newpoint^.next:=head;head:=newpoint;{这两步操作顺序不能颠倒,请分析为什么?}

表中插入

 

 

 

 

 

 

 

 

 

 

 

算法描述

申请一新结点newpoint

将数值赋值给newpoint的数据域;

将新结点newpoint的指针域赋值为插入点前一个结点(用p表示)的指针域;

newpoint的地址赋值给插入点前一个结点(用p表示)的指针域。

参考程序段:

new(newpoint);readln(x);newpoint^.data:=x;

newpoint^.next:=p^.next;p^.next:=newpoint;{这两步操作顺序不能颠倒,请分析为什么?}

表尾插入

 

 

 

 

 

 

 

 

 

 

 

算法描述

申请一新结点newpoint;

将数值赋值给newpoint的数据域,将NIL赋值给新结点newpoint的指针域;

newpoint的地址赋值给已建立的链表的尾结点(用q表示)的指针域。

参考程序段:

new(newpoint);readln(x);newpoint^.data:=x;newpoint^.next:=NIL;

q^.next:=newpoint;

3. 输入一个正整数序列,遇负数时停止,并按输入顺序反向输出。

问题分析:由于线性链表进行数据访问时只能从表头结点开始,根据问题要求可知,在线性链表建立时必须采用插入到表首的方法进行建立。

解决该问题需用的数据类型与上例相同,不再重复。

算法描述

表头指针置为NIL

输入一个数;

while 读入的数为正整数 do

              begin

                 申请一新结点;

                 将读入的数送入新结点的数据域;

                 将原表头指针赋给新结点的指针域;

                 将新结点的地址赋给表头指针;

                 读入下一个值;

              end;

顺序输出各结点的数据值。

参考程序:

program aa;

type

point=^node;

node=record

     data:integer;

     next:point;

   end;

  var p,q,head:point;

     x:integer;

  begin

head:=nil;readln(x);

while x>=0 do

  begin

    new(p);p^.data:=x;

    p^.next:=head;

    head:=p;

    readln(x);

  end;

p:=head;

while p<> nil do

  begin

    write(p^.data:8);

    p:=p^.next

  end;

writeln;

  end.

4. 设链表head中的数据是按从小到大顺序存放的,在链表中插入一个数,使链表仍有序。

  分析:显然,应分两步:查找、插入。设po指向要插入的结点,若仅知道po应插在p之前(作为p的前趋结点)是无法插入的,应同时知道p的前趋结点地址q。

  当然,如果插在链表原头结点这前或原链表为空表或插在原尾结点之后,则插入时又必须作特殊处理。

  过程如下:

  procedure inserting(var head:pointer;x:integer);

  var po,p,q:pointer;

  begin

   new(po); po ^.data:=x;

   p:=head;

   if head=nil{原表为空表}

    then begin

     head:=po;po^.next:=nil;

    end

   else begin

    while (p^.data<x)and(p^.next<>nil)do

    begin

     q:=p;p:=p^.next

    end;

    if p^.data>=x{不是插在原尾结点之后}

    then begin

      if head=p then head:= po

      else q^.next:= po;

      po ^.next:=p

     end

   else begin

      po ^.next:= po;

      po ^.next:=nil

    end;

   end;

  end;

完整程序参考:

program fdsa;

  type pointer=^node;

       node=record

        data:integer;

        next:pointer;

       end;

  var p,q,head: pointer;x,k,i:integer;

  procedure inserting(var head:bo;x:integer);

    var po,p,q:pointer;

     begin

      new(po); po ^.data:=x;

      p:=head;

     if head=nil

      then begin

        head:= po; po ^.next:=nil;

           end

      else begin

       while (p^.data<x)and(p^.next<>nil)do

        begin

         q:=p;p:=p^.next

        end;

      if p^.data>=x

      then begin

            if head=p then head:= po

              else q^.next:= po;

            po ^.next:=p

          end

       else begin

        p^.next:= po;

        po ^.next:=nil

        end;

    end;

    end;

  begin

   read(x);

   head:=nil;

   while x>=0 do

    begin

     if head=nil then

      begin

       new(p);p^.data:=x;p^.next:=nil;head:=p;q:=p;end

      else begin

       new(p);p^.data:=x;p^.next:=nil;q^.next:=p;q:=p;end;

     read(x);

    end;

    readln;

    read(k);

    inserting(head,k);

   p:=head;

   while p<>nil do

    begin

     write(p^.data,' ');

     p:=p^.next;

    end;

  end.

习题

完善程序

下面的程序是将数组a中存放的n个整数转存到单链表h.

program aa;

type point=^node;

      node=record

     data:integer;

     next:point;

   end;

var

  a:array[1..10] of integer;

  i:integer;

  head:point;

procedure creat(  var head:point     );

  var p,q:point;

     i:integer;

  begin

new(p);head:=p;

for i:=1 to 10 do

  begin

    

    p^.data:=a[i]; q:=p;

    new(p);

    (q^.next:=p)              

  end;

   (q^.next:=nil)             

  end;

procedure print(var head:point);

  var p:point;

  begin

p:=head;

while p<>nil do

  begin

    write(p^.data:6);p:=p^.next

  end

  end;

begin

  write(‘input an array:’);

  for i:=1 to 10 do read(a[i]);

  creat(head);

  print(head);

end.

六、线性链表结点的删除

线性链表结点的删除相对于插入操作来说,实现起来就简单得多。一般分两步完成:

1.把要删除的结点地址赋给一个临时变量;

2.把要删除的结点的指针域赋给要删除的结点的前一结点的指针域;

最后把将要删除的结点删除,释放存储单元。

在利用程序实现结点删除时,需要用到两个指针变量:变量q表示要删除结点的前一结点的地址,变量p表示要删除的结点的地址。下面的图示分别表示了删除表头结点、删除表中结点和删除表尾结点三种不同的情况。

 

 

 

 

 

 

`

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

参考程序段:

q:=head;p:=q^.next;head:=p;dispose(q);

 

 

 

 

 

 

 

 

 

 

 

 

参考程序段:

    q^.next:=p^.next;dispose(p);

 

 

 

 

 

 

 

 

 

 

参考程序段:

q^.next:=p^.next;dispose(p); 或者也可以用q^.next:=NIL;dispose(p)

被删除结点所占用的存储空间可以通过语句dispose(p),交还给系统。

因此,对于线性链表中操作总的来说可以分为:线性链表的建立、线性链表的输出、结点的查找、结点的插入和结点的删除。所有这些操作最关键的地方就是在于如何改变结点指针域的值。

掌握线性链表的访问基本方法是,从头结点开始沿线链表方向进行探求,一般用到两个指针型变量:一个用于指向刚查过的结点地址,另一个用于指向下一个待查的结点地址。

结束访问的条件有两 个:一个是结点地址为NIL,另一个是找到了相应的结点。

最容易出现的错误是,当pNIL时,取p^.data,因为当pNIL时,p^.data的值是无意义的。

5.设单链表h中存有若干个非负整数,删除所有值为素数的结点。

问题分析:该问题实际上是解决如何在链表中删除结点。解题的关键有两点:

(1) 沿链表顺序对结点的数据域逐个进行是否为素数的判断;

(2) 删除时要分清是删除链表中的结点还是链表尾的结点。

算法分析:

(1) 根据数据输入的顺序建立链表;

(2) 从表头结点开始沿链表方向对结点的数据域逐个进行是否为素数的判断,删除是素数的结点;

if  p 结点数据域为素数  then 

if  p 结点是表头结点 then 修改表头 else 删除结点;

(3) 输出删除后的链表。

画结点链表,有助理解

参考程序:

program aa;

type

  point=^node;

  node=record

data:integer;

next:point;

      end;

var

  head1:point;

function sushu(x:integer):boolean;

var

  found:boolean;

  i:integer;

begin

  found:=true;

  if (x=0) or (x=1) then found:=false;

  if x=2 then found:=true;

  for i:=2 to x-1 do

    if x mod i=0 then found:=false;

  sushu:=found

end;

procedure creat(var head:point);

  var

    x:integer;

    p,q:point;

  begin

    head:=nil;q:=head;

    read(x);

    while x>=0 do

      begin

        if head=nil then

          begin

            new(p);p^.data:=x;

            head:=p;q:=p

          end

        else 

          begin

            new(p);q^.next:=p;

            p^.data:=x;q:=p

          end;

        read(x)

      end;

    q^.next:=nil

  end;

procedure delete(var head:point);

  var

    p,q:point;

  begin

    p:=head;q:=head;

    while p<>nil do

      begin

        if sushu(p^.data)

        then if  p=head

            then begin head:=p^.next;q:=head end

            else q^.next:=p^.next

        else q:=p;

        p:=p^.next

     end;

 end;

procedure print(head:point);

       var

    p:point;

  begin

    p:=head;

    if p=nil then 

       writeln(‘no solution!’)                             { [sə'lju:ʃən] 解答}

    else 

      while p<>nil do

      begin

        write(p^.data:6);

        p:=p^.next

      end;

    writeln

  end;

begin

write(‘input a link:’);

 creat(head1);

delete(head1);

print(head1)

end.

测试运行结果如下:

输入:2  3  6  8  9  7  -1

输出:6  8  9

输入:2  3  5  7  -1

输出:no solution!

输入:4  6  8  9  13  1

输出:4  6  8  9

6.在一个有序链表中装有1100100个整数。要求任意输入100以内的一个整数,把它从链表中删除。

 

               PROGRAM e1(input,output);

                TYPE point=^pp;

                     pp=record

                        data:integer;

                        link:point;

                        end;

                VAR

                   p1,p2,p3,k:point;

                   i:integer;

                BEGIN

                  {建立一个1――100的整数的有序链表}

                   new(p1);

                   k:=p1;

                   p1^.data:=1;

                   for i:=2 to 100 do

                     begin

                      new(p2);

                      p2^.data:=i;

                      p1^.link:=p2;

                      p1:=p2;

                    end;

     p2^.link:=nil;

     {输入要删除的结点的DATA}

                   new(p3);

                   writeln('input p3');

                   readln(p3^.data);

                   P1:=k;p2:=k;

                    {P2指针查找P3结点}

                   while p2^.data<p3^.data do

     p2:=p2^.link;

                    {P1指针定位于P3之前}

                   while p1^.link<>p2 do

                     p1:=p1^.link;

                   p1^.link:=p2^.link;

                   dispose(p3);{P3结点的空间释放}

                    {输出修改后的链表}

                   repeat

                        write(k^.data,'->');

                        k:=k^.link;

                    until k^.data=100;

                    write(k^.data);

                END.

7.将链表head中值为X的第一个结点删除

  分析有三种情况存在:头结点的值为X; 除头结点外的某个结点值为X;无值为X的结点。为将前两种情况统一起来, 我们在头结点之前添加一个值不为X的哨兵结点。

  算法分两步:查找、删除。

  过程如下:

  procedure deleting(var head:pointer;x:integer);

  var p,q:pointer;

  begin

   New(p);p^.data:=x-1;p^.next:=head;

   head:=p;{以上为添加哨兵结点}

   while(x<>p^.data)and(p^.next<>nil) do

   begin

    q:=p;

    p:=p^.next

   end;

   if x=p^.data{存在值为X的结点}

   then q^.next:=p^.next

   else writeln('not found!');

   head:=head^.next{删除哨兵}

  end;

小结:

本题主要是帮助大家掌握链表中结点删除的方法。结点删除的要点在于要分清楚删除的结点是否为表头结点,如果是表头结点,则需要将表头地址进行修改。当然本参考算法不是最好的。解决这一问题还可以直接通过建立链表的方法实现,只是在新建结点时需要对输入的数据进行是否为素数的判断,对满足条件的数据才链接到链表中,相关程序请同学们自行编写。

习题

阅读程序:

1.建立一个有10个结点的链表,最后输出该链表。

 PROGRAM  E1INPUTOUTPUT);

                TYPE point=^pp;

                     pp=record

                        data:string[5];

                        link:point;

                        end;

                VAR

                   p1,p2,k:point;

                   i:integer;

                BEGIN

                  {产生新结点P1,作为链表的头}

                   new(p1);

                   writeln('input data');

                   readln(p1^.data);

                   {指针K指向链表头

                   k:=p1;

                   {用循环产生9个新结点,每个结点都接在上一个结点之后}

                   for i:=1 to 9 do

                    begin

                      new(p2);

                      writeln('input data');

                      readln(p2^.data);

                      p1^.link:=p2;

                      p1:=p2;

    end;

    {给最后一个结点的LINK域赋空值NIL}

     p2^.link:=nil;

    {从链表头开始依次输出链表中的DATA}

                    while k^.link<>nil do

                     begin

                        write(k^.data,'->');

                        k:=k^.link;

                     end;

                   END.

 

  在本程序里,输出链表的过程就是一个链表的遍历。给出一个链表的头结点,依次输出后面每一个结点的内容,指针依次向后走的语句用K:=K↑.LINK  来实现。

2.读入一批数据,遇负数时停止,将读入的正数组成先进先出的链表并输出。

分析:首先应定义指针类型,结点类型和指针变量,读入第一个值,建立首结点,读入第二个值,判断它是否大于零,若是,建立新结点。

 

PROGRAM fifo(input,output);

{建立先进先出链表}

TYPE

  Point=^node;

    Node=RECORD

Data:real;

Link:point

END;

VAR

   head,last,next:point;

   x:real;

BEGIN

{读入第一个值,建立首结点}

   read(x);

   write(x:6:1);

   new(head);

   head^.data:=x;

   last:=head;

{读入第二个值}

   read(x);

   write(x:6:1);

   WHILE x>=0 DO

      BEGIN

      {建立新结点}

         new(next);

         next^.data:=x;  

         last^.link:=next; {链接到表尾}

         last:=next;     {指针下移}

         read(x);        {读入下一个值}

         write(x:6:1)

    END;

    Writeln;         

Last^.link:=NIL;       {表尾指针域置NIL}

Next:=head;

    WHILE next<>NIL DO  {输出链表}

BEGIN 

   Write(next^.data:6:1);

   Next:=next^.link

END;

  Writeln

END.

3.建立一个有序的整数链表,再将一任意整数插入进链表,使链表仍然有序。

 

               PROGRAM e1(input,output);

                TYPE point=^pp;

                     pp=record

                        data:integer;

                        link:point;

                        end;

                VAR

                   p1,p2,p3,k:point;

                 BEGIN

                    {建立一个整数的链表,要求输入的整数依次是有序的,以数9999结束}

                   new(p1);

                   writeln('input data');

                   readln(p1^.data);

                   k:=p1;

                   repeat

                      new(p2);

                      writeln('input data');

                      readln(p2^.data);

                      p1^.link:=p2;

                      p1:=p2;

                    until p2^.data=9999;

                    p2^.link:=nil;{有序链表建立完毕}

                   writeln('input p3');

                   readln(p3^.data);

                   p1:=k;p2:=k;{P1P2都指向表头}

                    {P2找到插入点后一个结点}

                   while p2^.data<p3^.data do

     p2:=p2^.link;

                    {P1找到插入点以前的结点}

                   while p1^.link<>p2 do

                     p1:=p1^.link;

                    {P3接入P1P2之间}

                   p1^.link:=p3;

                   p3^.link:=p2;

                   {将整个插入后的链表依次打印出来}

     repeat

                        write(k^.data,'->');

                        k:=k^.link;

                    until k^.data=9999;

                    write(k^.data);

                END.

4.建立一个若干整数的链表后(-1结束)再从链表中删除从键盘上输入一个整数的所有结点.(程序

链表的删除程序如下:

program lianbiao;

type link=^data;

     data=record

     num:integer;

     next:link;

     end;

var head,p,tail,r:link;

i,x:integer;

begin

  writeln('input lbdata:');

  head:=nil;

  readln(i);

  while i<>-1 do

   begin

   new(p);

   p^.num:=i;

   p^.next:=nil;

  if head=nil then begin head:=p; tail:=p end

     else begin tail^.next:=p; tail:=p end;

  readln(i);

  end;

  write('input delete integer:');

  readln(x);

  p:=head;

  while p<>nil do

   begin

    if p^.num=x then

     if p=head then begin head:=p^.next;p:=head end

               else if p^.next<>nil  then

                       begin r^.next:=p^.next ;p:=p^.next end

                              else

                             begin r^.next:=nil;p:=nil end

     else begin r:=p;p:=p^.next end;

  end;

  p:=head;

  while p<>nil do

   begin

   write(p^.num:6);

   p:=p^.next;

   end;

  readln;

end.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

       

posted @ 2010-10-11 20:54  lj_cherish  阅读(662)  评论(0)    收藏  举报