交换单链表第n和n+1个链点
带头结点的单链表,头指针为h,编写算法,实现单链表中第n个结点和第n+1个结点相互交换,如果n为尾结点,需要向用户输出提示信息,代表交换失败,返回0,若交换成功返回1,并打印交换后的单链表。
这个题主要难点 :
1.判断是否满足有n+1个节点。
2. 交换这俩个节点的位置
该单链表的存储结构
typedef int DataType;
typedef struct Node
{
DataType data; // data域用于存储数据元素
struct Node *next; // next域用于存放指向其后继的指针
}LNode, *PNode, *LinkList; // LinkList为头指针
// **初始化函数**
int InitLinkList(LinkList *head)
{
*head = (LinkList)malloc(sizeof(LNode));
if (!head)
{
printf("初始化链表错误!\n");
return 0;
}
(*head)->next = NULL;
return 1;
}
// **求链表长度函数**
int LinkListLength(LinkList head)
{
int length = 0;
PNode p = head->next;
while (p)
{
length++;
p = p->next;
}
return length;
}
//**判断链表是否为空函数**
int LinkListEmpty(LinkList head){
if (head->next) {
return 0;
}
else {
return 1;
}
}
//**插入函数**
int LinkListInsert(LinkList h, int pos, DataType x)
{
PNode p = h, q;
int i = 0;
while (p && i < pos- 1)
{
p = p->next;
i++;
}
if (!p || i > pos - 1)
{
printf("插入位置不合法!\n");
return 0;
}
q = (PNode)malloc(sizeof(LNode));
if (!q)
{
printf("不能生成新结点\n");
return 0;
}
q->data = x;
q->next = p->next;
p->next = q;
return 1;
}
// **摧毁链表函数**
void DestroyLinkList(LinkList h)
{
PNode p = h->next;
while (h)
{
p = h;
h = h->next;
free(p);
}
}
//**遍历链表函数**
void TraverseLinkList(LinkList h)
{
PNode p = h->next;
while (p)
{
printf("%d ", p->data);
p = p->next;
}
printf("\n");
}
// **用于和下面语句一起判断交换是否成功**
// 其实这个函数可以不用直接在主函数中判断即可
PNode findN(LinkList a,int n)
{
int cnt = 1;
PNode p = a;
while( p && cnt <= n )
p = p->next;
cnt++;
return p;
}
// **交换链点位置函数**
int SwapN_inList( LinkList a , int posN , int *len)
{
LinkList A , q,p;
int n =1, num =0;
A=a->next;
while(A) // 统计节点个数
{
num++;
A = A->next;
}
*len = num;
if(posN >= num) // 判断是否满足有n+1个节点
{
return 0;
}
A = a->next;
while(1)
{ // 找到待交换节点
if(n == posN-1)
{
q = A->next; //第n个节点
p = q->next; // 表示第n+1个节点
A->next = q->next;
q->next = p->next;
p->next = q;
break;
}
n++;
A = A->next;
}
return 1;
}
// **主函数**
int main()
{
LinkList h;
char ch;
PNode s1=NULL,s2=NULL,s3=NULL,s4=NULL;
DataType x,N;
int length = 0, pos = 1;
InitLinkList(&h);
do
{
scanf("%d",&x);
LinkListInsert( h , pos++ , x );
}while((ch=getchar())!='\n');
scanf("%d",&N);
s1 = findN(h,N);
if (s1)
{
s2 = s1->next;
}
if ( SwapN_inList( h , N , &length) == 1 )
{
s3 = findN(h,N);
if (s3)
{
s4 = findN(h,N+1);
}
if ( s1 == s4 && s2 == s3 )
{
printf("交换第%d个和第%d个链点位置后的单链表A是\n", N , N+1 );
TraverseLinkList( h );
}
}
else
{
printf("单链表A的第%d个结点为尾结点,没有下一个结点与之交换\n", length);
}
DestroyLinkList( h );
return 0;
}