将单向链表中关键字的值重复的结点删除,使得链表中各结点的值均不相同。
//12.5.cpp
#include "stdafx.h"
#include"LinkList.h"
#include<iostream>
#include<string>
using namespace std;
int main()
{ LinkNode<int>IntegerLList;
LinkNode<int>*head;
const int N=100;
int a[N]={3,2,4,5,5,6,6,6};
IntegerLList.DeleteSame(head);
IntegerLList.Printf(head);
return 0;
}
template<class T>
class LinkNode
{
template<class T>
friend class LinkList;
public:
LinkNode()
{ next=NULL;}
void CreatNew(int n,int a[]);
void DeleteSame(LinkNode*head);
void Printf(LinkNode*head);
private:
T data;
LinkNode<T>*next;
};
//LinkList.cpp
#include "StdAfx.h"
#include"LinkList.h"
template<class T>
void LinkNode<T>::CreatNew(int n,int a[])
{ LinkNode<T>*head;
LinkNode<T>*tail;
LinkNode<T>*p;
head=NULL;
for(int i=0;i<n;i++)
{ p=new LinkNode<int>;
p->data=a[i];
p->next=NULL;}
if(!head)
{ head=tail=p;
tail->next=NULL;}
else
{ tail=tail->next=p;
tail->next=NULL;}
return head;}
//LinkList.h
template<class T>
void LinkNode<T>::DeleteSame(LinkNode*head)
{ LinkNode<T>*key;
LinkNode<T>*p;
LinkNode<T>*q;
key=head;
while(key)
{ p=key;
q=key->next;
if(q!=NULL&&p!=NULL&&p->data==q->data)
{
p->next=q->next;
delete q;}
key=key->next;}}
template<class T>
void LinkNode<T>::Printf(LinkNode<T>*head)
{
LinkNode<T>*p=head;
for(;p;p=p->next)
cout<<"删除后的数表为:"<<p->data;}
给你写了一个简单的参考。如果链表都是整形的话,不要用模板和类,简单东西复杂化。
//LinkList.h
#include<iostream>
typedef struct LinkNode
{
int data;
struct LinkNode *next;
} ;
//函数声明:
// 创建带头节点单链表
LinkNode *CreatNew(int arr[], int len);
//打印单链表
void Printf(LinkNode*head);
//删除重复项
LinkNode *DeleteSame(LinkNode*head);
//LinkList.cpp
#include<iostream>
#include"LinkList.h"
using namespace std;
// 尾插法创建单链表(带头节点)
LinkNode *CreatNew(int arr[], int len)
{
LinkNode *head = (LinkNode *)malloc(sizeof(LinkNode)); // 生成头节点
head->next = NULL;
LinkNode *end = head; // 尾指针初始化
for (int i = 0; i < len; i++) {
LinkNode *p = (LinkNode *)malloc(sizeof(LinkNode)); // 为每个数组元素建立一个节点
p->data = arr[i];
end->next = p; // 将节点p插入到终端节点之后
end = p;
}
end->next = NULL; // 单链表建立完毕,将终端节点的指针域置空
return head;
}
// 单链表打印
void Printf(LinkNode *head)
{
if (head == NULL) return;
LinkNode *p = head->next;
while (p != NULL) {
printf("%d ", p->data);
p = p->next;
}
}
// 删除重复项(带头节点的单链表)
LinkNode *DeleteSame(LinkNode *head)
{
LinkNode *p, *q, *r, *temp;
LinkNode *s = head;
p = s->next;
int flag = 0; // flag用于标记在下一步遍历中,p后面的节点中 是否存在 与当前的p节点 相同的节点,若有,则flag为1;
while (p != NULL) // p用于遍历链表,每次遍历过程中,用p节点和p后面的节点依次比较;
{
q = p;
while (q->next != NULL) // q遍历p后面的结点,并与p数值比较
{
if (q->next->data == p->data)
{
flag = 1; // flag为1,则在当前遍历结束后,删除当前的p节点;
r = q->next; // r保存需要删掉的结点
q->next = r->next; // 需要删掉的结点的前后结点相接
free(r);
}
else
q = q->next;
}
if (flag == 0)
{
s = p;
p = p->next;
}
else
{
flag = 0; // 删除当前的p节点时,flag重新置为0;
temp = p;
p = p->next;
s->next = p;
free(temp);
}
}
return head;
}
//main.cpp
#include"LinkList.h"
#include<iostream>
#include<string>
using namespace std;
int main()
{
const int N = 100;
int a[] = { 3,2,4,5,5,6,6,6 };
LinkNode* head = CreatNew(a, 8);//需要创建一个带头节点的链表
DeleteSame(head);
Printf(head);
system("pause");
return 0;
}
//LinkList.cpp
#include "stdafx.h"
#include"LinkList.h"
template<class T>
void LinkNode<T>::CreatNew(int n, int a[])
{
LinkNode<T>* head;
LinkNode<T>* tail;
LinkNode<T>* p;
head = NULL;
for (int i = 0; i < n; i++)
{
p = new LinkNode<int>;
p->data = a[i];
p->next = NULL;
}
if (!head)
{
head = tail = p;
tail->next = NULL;
}
else
{
tail = tail->next = p;
tail->next = NULL;
}
return head;
}
//LinkList.h
#pragma once
#include<iostream>
#include<string>
using namespace std;
template<class T>
class LinkNode
{
template<class T>
friend class LinkList;
public:
LinkNode()
{
next = NULL;
}
void CreatNew(int n, int a[]);
void DeleteSame(LinkNode* head);
void Printf(LinkNode* head);
private:
T data;
LinkNode<T>* next;
};
template<class T>
void LinkNode<T>::DeleteSame(LinkNode* head)
{
LinkNode<T>* key;
LinkNode<T>* p;
LinkNode<T>* q;
key = head;
while (key)
{
p = key;
q = key->next;
if (q != NULL && p != NULL && p->data == q->data)
{
p->next = q->next;
delete q;
}
key = key->next;
}
}
template<class T>
void LinkNode<T>::Printf(LinkNode<T>* head)
{
LinkNode<T>* p = head;
for (; p; p = p->next)
cout << "删除后的数表为:" << p->data;
}
//Source.cpp
#include "stdafx.h"
#include"LinkList.h"
#include<iostream>
#include<string>
using namespace std;
int main()
{
LinkNode<int>IntegerLList;
LinkNode<int>* head=new LinkNode<int>;
const int N = 100;
int a[N] = { 3,2,4,5,5,6,6,6 };
IntegerLList.DeleteSame(head);
IntegerLList.Printf(head);
return 0;
}
变量未初始化。
就是找不到函数啊,你调用的函数或者模板在main函数下面,就找不到了。
举个例子来说:
int test1(int a){
return a+1;
}
int main(){
int a=10;
test1(a);//这个对
test2(a);//这个会报错,test2在面的下面,执行main的时候找不到test2。
return 0;
}
int test2(int a){
return a-1;
}
解决这种问题的方法就是,在main函数开始之前声明一下你要调用的函数。
//在最前面声明函数,函数的参数要全部写上去,有默认值可以不写在声明,写在实现部分
//这样编译器会主动寻找函数
int test01(int a);
int test03(int a);
int test02(int a);
int test1(int a){
return a+1;
}
int main(){
int a,b,c,d=10;
a=test1(d);
b=test2(d);
c=test3(d);
return 0;
}
int test2(int a){
return a-1;
}
int test3(int a=20){
return a-1;
}