单链表

本文介绍了一个链表数据结构的实现及其基本操作,包括创建、插入、删除等,并展示了如何利用链表解决实际问题,如按指定序号打印元素、求两个有序链表的交集与并集。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

typedef int ElementType;

/*List.h*/
#ifndef _List_H
#define _List_H

struct Node;
typedef struct Node *PtrToNode;
typedef PtrToNode List;
typedef PtrToNode Position;

List MakeEmpty( List L );
int IsEmpty( List L );
int IsLast( Position P, List L );
Position Find( ElementType X, List L );
void Delete( ElementType X, List L );
Position FindPrevious( ElementType X, List L );
void Insert( ElementType X, List L, Position P );
void DeleteList( List L );
Position Header( List L );
Position First( List L );
Position Advance( Position P );
ElementType Retrieve( Position P );

#endif /* _List_H */

/*fatal.h*/
#include <stdio.h>
#include <stdlib.h>

#define Error( Str ) FatalError( Str )
#define FatalError( Str ) fprintf( stderr, "%s\n", Str ), exit( 1 )
/////////////////


#include <stdio.h>
#include <stdlib.h>
#include "list.h"
#include "fatal.h"

struct Node
{
ElementType Element;
Position Next;
};

List MakeEmpty(List L)
{
if(L != NULL)
DeleteList(L);
L = (List)malloc(sizeof(struct Node));
if(L == NULL)
FatalError("Out of memory!");
L->Next = NULL;
return L;
}

int IsEmpty(List L)
{
return L->Next == NULL;
}

int IsLast(Position P, List L)
{
return P->Next == NULL;
}

Position Find(ElementType X, List L)
{
Position P;

P = L->Next;
while(P != NULL && P->Element != X){
P = P->Next;
}

return P;
}

void Delete(ElementType X, List L)
{
Position P, TmpCell;

P = FindPrevious(X, L);

if(!IsLast(P, L)){
TmpCell = P->Next;
P->Next = TmpCell->Next;
free(TmpCell);
}
}

Position FindPrevious(ElementType X, List L)
{
Position P;

P = L;
while(P->Next != NULL && P->Next->Element != X)
P = P->Next;

return P;
}

void Insert(ElementType X, List L, Position P)
{
Position TmpCell;

TmpCell = (List)malloc(sizeof(struct Node));
if(TmpCell == NULL)
FatalError("Out of space!");

TmpCell->Element = X;
TmpCell->Next = P->Next;
P->Next = TmpCell;
}

void DeleteList(List L)
{
Position P, Tmp;

P = L->Next;
L->Next = NULL;
while(P != NULL){
Tmp = P->Next;
free(P);
P = Tmp;
}
}
/*
Position Header(List L)
{
return L;
}

Position First(List L)
{
return L->Next;
}

Position Advance(Position P)
{
return P->Next;
}

ElementType Retrieve(Position P)
{
return P->Element;
}
*/
////////////////////////////////////////////
/*List.c*/
void PrintList(List L)
{
Position P = L->Next;
while(P != NULL){
printf("%d\t", P->Element);
P = P->Next;
}
printf("\n");
}

List InitList(int * arr, int size)
{
List L = NULL;
L = MakeEmpty(L);
int i;
for(i = size - 1; i >= 0; i--)
Insert(*(arr+i), L, L);
return L;
}

//两个升序链表,打印tarList中的对应元素,这些元素的序号由seqList指定
void PrintLots(List tarList, List seqList)
{
int seq, i;
int lastPos = 1;
Position pSeq = seqList->Next;
Position pTar = tarList->Next;

while(pSeq != NULL && pTar != NULL){

seq = pSeq->Element;
for(i = lastPos; i < seq; i++){
pTar = pTar->Next;
lastPos++;
if(pTar == NULL){
printf("Over\n");
return;
}
}
printf("%d\t", pTar->Element);
pSeq = pSeq->Next;
}
printf("\n");
}

//使用单链表交换相邻元素
void SwapWithNext(Position BeforeP, List L)
{
Position P, AfterP;

P = BeforeP->Next;
AfterP = P->Next;

P->Next = AfterP->Next;
BeforeP->Next = AfterP;
AfterP->Next = P;
}

/*
//使用双链表交换相邻元素
void SwapWithNext2(Position P, List L)
{
Position BeforeP, AfterP;

BeforeP = P->Prev;
AfterP = P->Next;

P->Next = AfterP->Next;
BeforeP->Next = AfterP;
AfterP->Next = P;
P->Next->Prev = P;
P->Prev = AfterP;
AfterP->Prev = BeforeP;
}
*/

//已升序排序的表L1,L2,求交集
List Intersect(List l1, List l2)
{
List L = NULL;
L = MakeEmpty(L);
Position P = L;
Position P1 = l1->Next;
Position P2 = l2->Next;
while(P1 != NULL && P2 != NULL){
if(P1->Element == P2->Element){
Insert(P1->Element, L, P);
P = P->Next;
P1 = P1->Next;
P2 = P2->Next;
}
else if(P1->Element < P2->Element)
P1 = P1->Next;
else
P2 = P2->Next;
}
return L;
}

//已升序排序的链表L1,L2,求并集
List Join(List l1, List l2)
{
List L = NULL;
L = MakeEmpty(L);

Position P = L;
Position P1 = l1->Next;
Position P2 = l2->Next;
while(P1 != NULL && P2 != NULL){
if(P1->Element == P2->Element){
Insert(P1->Element, L, P);
P1 = P1->Next;
P2 = P2->Next;
}else if(P1->Element < P2->Element){
Insert(P1->Element, L, P);
P1 = P1->Next;
}else{
Insert(P2->Element, L, P);
P2 = P2->Next;
}
P = P->Next;
}

while(P1 != NULL){
Insert(P1->Element, L, P);
P1 = P1->Next;
P = P->Next;
}
while(P2 != NULL){
Insert(P2->Element, L, P);
P2 = P2->Next;
P = P->Next;
}

return L;
}

//单链表就地置逆
List Reverse(List L)
{
Position prev = NULL;
Position curr = L->Next;
Position next = curr->Next;
while(next != NULL){
curr->Next = prev;
prev = curr;
curr = next;
next = next->Next;
}
curr->Next = prev;
return curr;
}


int main()
{
int tarArr[] = {1,2,3,4,5,6,7,8,9};
int seqArr[] = {1,4,9,16};
List target = InitList(tarArr, 9);
List sequence = InitList(seqArr, 4);
PrintList(target);
PrintList(sequence);
PrintLots(target, sequence);
PrintList(Intersect(target, sequence));
PrintList(Join(target, sequence));
PrintList(Reverse(target));
return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值